#clojure logs

2014-08-31

00:20meoblast001is there a way to map in clojure and get the previous item without using reduce?
00:33xeqi,(map (juxt identity inc) [1 2 3])
00:33clojurebot([1 2] [2 3] [3 4])
00:33xeqimeoblast001: ^ ?
00:34maravillas,(let [c (range 4)] (map vector c (drop 1 c)))
00:34clojurebot([0 1] [1 2] [2 3])
00:34meoblast001hmm. that works i think
00:34xeqior did you mean the previous in the list?
00:34meoblast001previous or next works really
00:34maravillas,(map identity (partition 2 1 (range 4)))
00:34clojurebot((0 1) (1 2) (2 3))
00:35xeqimeoblast001: then something like maravillas's answer
00:35meoblast001hmm
00:35meoblast001i don't think i understand juxt :/
00:36meoblast001maravillas: ah, yes. just throwing the partition in could do it
00:36meoblast001thanks
00:36maravillaswelcome :)
00:36gws,(map (juxt inc) [1 2 3])
00:37clojurebot([2] [3] [4])
00:37gws,(map (juxt inc dec) [1 2 3])
00:37clojurebot([2 0] [3 1] [4 2])
00:38gwsmeoblast001: does that help?
00:39meoblast001hmm
00:39gwsso juxt produces a new function which will call each of the functions you passed to it on the element you give the new 'juxt-function', and return a vector with those results
00:39meoblast001so it takes arbitrary functions with 2 parameter
00:39meoblast001and creates one function with 1 parameter
00:40gwsyou can give juxt as many functions as you like
00:40gwsas i did above
00:40meoblast001that 1 parameter is a list,and it applies those arbitrary functions to all of those functions to each element in the list
00:40meoblast001hmmm okay
00:40meoblast001makes sense. thanks
00:40gws,(map (juxt inc dec inc dec) [1 2 3])
00:40clojurebot([2 0 2 0] [3 1 3 1] [4 2 4 2])
00:41meoblast001,((juxt inc dec) 5)
00:41clojurebot[6 4]
00:41meoblast001yeah, makes sense
00:50wildnuxwhen i do (seq "abcd") it shows ("a", "b", "c", "d") in clojurescript but shows (\a, \b, \c, \d) in clojure, why is it different, and how do i know which "seq" funtion i am using?
00:51wildnuxhow do i know the full namespaced form of a function or var?
00:52rhg135wildnux, in js there are no characters, they're single char strings
00:53wildnuxrhg135: aah :)
00:53wildnuxrhg135: how do i get the full namespaced form of a function/symbol/vars in clojure?
00:53wildnuxi thought #'varname would show but it doesnot :D
00:53rhg135,(symbol (resolve '+))
00:53clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.String>
00:53rhg135hmm
00:55rhg135,(symbol (-> (resolve '+) str (subs 2)))
00:55clojurebotclojure.core/+
00:55rhg135very hackish tho
00:55vermathe syntax quote should work too right?
00:55verma,`+
00:55clojurebotclojure.core/+
00:55rhg135oh
00:55rhg135duh
00:55rhg135thank you
00:56verma:)
00:56wildnuxwhat does resolve do?
00:56rhg135resolves a symbol to a var in clj
01:02fifosine,(let [word "0123"]
01:02fifosine (loop [coll (butlast word)]
01:02fifosine (if (empty? coll)
01:02fifosine (println (last word))
01:02fifosine (do
01:02fifosine (println (first coll))
01:02fifosine (println "join")
01:02clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
01:02fifosine (recur (rest coll))))))
01:07opqdonutfifosine: you should've given the whole sexp on one line
01:15fifosineWhat's a macro that will take something like
01:15fifosine,(take 5 (repeat '(println 5)))
01:15clojurebot((println 5) (println 5) (println 5) (println 5) (println 5))
01:15fifosineand wrap it in a do form?
01:57blaenkI realize this may be a very broad/open question, but can anyone imagine why it takes two sends for my core.async to register a receive?
01:58blaenkI made the channel with (chan), and am only using put! and <!
02:16harjaHi all, a very dumb question, how do I perform a long lasting calculation once and bind it to a name in the ns? I tried (def foo (filter ... pmap ....))
02:17harjahm, now it was instantaneous... what the
02:17harjaSo that is the right way then? :)
07:50kqrharoldwu, your question isn't entirely clear, but it's possible that filter/map doesn't perform the computation until it is needed, and then it's only done once
07:50kqrharoldwu, never mind
07:50kqrharoldwu, that was meant for someone else who isn't hear anymore and i'm tired enough to not notice the tab completion going wrong
07:54Rhainurkqr: haha I was trying to figure out where the question was
08:18martinklepschin the core.async documentation functions like map< have a note "Deprecated - this function will be removed. Use transformer instead" — whats a transformer in that context?
08:18john2xhello. how do I stop a function from running in a CIDER repl?
08:19john2xmartinklepsch: I think they refer to transducers http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming
08:21john2xthe post includes an example using it with channels.. so the doc could be a typo/needs updating..
08:21kqryeah that looks like that'd be it
08:23john2xah here "So, reducing function transformers are getting a name - 'transducers', and first-class support in Clojure core and core.async."
08:30kqris there some version of contains? that works for a set of keys, and checks if all of them exists in the indexable? (as opposed to some which only checks for if at least one of them exists)
08:31martinklepschjohn2x: that was the first thing that popped to my mind as well but the name confused me. thanks!
08:32kqrah, (every?) does that, it seems
08:32kqrwait no
08:32kqrthat's not quite it either I don't think
08:35john2xkqr: superset?
08:35john2xah but both needs to be sets
08:36kqryeah
08:36kqrif it helps, what is happening is that i'm trying to write a test for a function that returns a map
08:36kqrthat map is supposed to have a few things
08:36kqrthough now that I say it
08:36kqri think I might be doing the entire thing wrong
08:52kqrbut how *do* I express "I want this map to be equal to this map except it might contain some more things?"
08:52kqrit's not a transitive relation, but it shouldn't be too weird anyway, I think
08:53kqrit's like superset? but for maps
08:54kqrI guess I can convert to sets and then check superset?
08:54ephemeronkqr: There are many ways to approach the problem; if you would like to use sets, you can just extract the keys from the map with `keys`.
08:55kqrephemeron, in this case I realised I want keys and values
08:55john2xhmm why does `((fn [] [:a :b]))` work but `(#([:a :b]))` doesn't?
08:55kqrephemeron, so I have a function that returns {:name "kqr" :age 27 :occupation :unemployed} and I want to check that it contains *at least* {:name "kqr" :age 27}
08:55kqrbut it can contain more than that
08:56kqrjohn2x, it evaluates the thing inside #() as something inside normal parens
08:56kqrjohn2x, with the exception of argument expansion
08:57kqrjohn2x, so it tries to interpret your vector as a function or special form, I guess?
08:57kqrjohn2x, #(quote [1 2]) works
08:57kqrjohn2x, so does #(identity [1 2])
08:58ephemeronkqr: Are you looking to validate the values, or just check if they are present?
08:58john2xoh so it's more ((fn [] ([:a :b])))?
08:58kqrjohn2x, exactly
08:58john2xok, makes sense. thanks
08:58kqrephemeron, i'm writing a test for a parser. i give it a string and I want to check that it gives me the correct map back (which contains the result of the parse)
09:01ephemeronkqr: If you trust the values and only want to verify that the required keys are present,
09:02ephemeronyou could do e.g. (superset? (into #{} (keys some-map)) required-keys)
09:02kqrephemeron, I don't trust the values :>
09:07ephemeronIf it is just for a one-off predicate, you could convert both the to-be-tested map and the test-map to sets; for full validation, you might want to seek a library.
09:09kqrthanks
09:09ephemerone.g. (into #{} {:a 1 :b 2 :c 3}) is a superset of (into #{} {:a 1 :b 2})
09:09ephemeronbut not of (into #{} {:a 1 :b 3}).
09:12kqris there a particular reason to use (partial into #{}) instead of (set)?
09:12gfrederickskqr: into uses transients
09:12gfredericksuntil 1.7, then clojure.core/set should be upgraded to use transients as well
09:13kqrah
09:40kqrwow I went from trying to write a few tests to majorly reworking parts of my design to be much better
09:40kqrthat's what I really like about tests
10:44kqrhm
10:44kqrwhat I don't like is that so many functions return nil when they fail
10:46mi6x3mkqr: why is this?
10:47kqrmaybe that's just me but it feels like I have to do so many explicit checks
10:47kqrthough perhaps I should just set up a precondition on my function that guarantees no nils creeping in
10:51kqrmi6x3m, what my function does is it takes a map, and then produces a new map from it
10:51kqrmi6x3m, but if the original map doesn't have all the values it's supposed to, the new map will contain nils in certain places
10:51kqrmi6x3m, which is bad
10:52kqrmi6x3m, because then i'll use the new map expecting it to have no nils in those places, and whenever the program finally crashes or shows bad behaviour, the cause is far from the effect
10:55thesaskwatchHi, why when I do (swap! (atom "abc") str "def") I get abcdef instead of def?
10:57thesaskwatchok, now I know
10:57thesaskwatchnvm
10:57ephemeronthesaskwatch: `swap!` passes the current value of the atom to the applied function.
10:57ephemeronYou most likely want `reset!`
10:58thesaskwatchephemeron: thanks .. you I should just read the friendly manual
10:58thesaskwatchyou -> yeah
10:59jbaiterwhen i open a repl with 'lein repl', how can I add the current working directory to the classpath?
11:00jbaiterwhen i try to do '(use my-ns)' it says that it can't find "my_ns.clj" on the classpath, even though a file with that name exists in the directory i start the repl from
11:18fifosineI've got these two function which follow the same form https://www.refheap.com/89623 in which a no-arg, side-effectful function is executed in between the execution of a one-arg, side-effectful function for each element in a list. Is there a way to write a function that abstracts this form based on the two functions and the collection?
11:25mi6x3mfifosine: some more info please?
11:25mi6x3mI see they are quite similar
11:25fifosinemi6x3m: What info do you need?
11:25mi6x3myet how many such functions do you expect to have?
11:25fifosineI expect 1 function to abstract the similar functionality seen in the paste
11:26mi6x3mehm, i'm not sure if I am going to do that
11:26mi6x3min fact, in their current form
11:26mi6x3mboth functions are extremely hard to comprehend
11:27mi6x3mfor someone else than you
11:28fifosinemaybe I can make more sense of them: the doseq is there only to execute the list of functions that's being created. the list of functions is created by the interposing of 1) a sleep function and 2) a function that makes a noise for each dit-dah in a khar
11:28fifosinethat's in the first function
11:29fifosinethe second is the same but the sleep function is different and it makes noises for each khar in a word instead of dit-dah in a khar
11:33mi6x3mfifosine: I see
11:33mi6x3mwell, I would first start by abstracting the xyz-to-sound function
11:34mi6x3mbecause they are quite similar
11:34fifosineright, that's what I'm asking for help on
11:35mi6x3mfifosine: first, let's see about the states
11:35mi6x3mword-to-sound has side effects so I think 'read-word!' is more suitable
11:35mi6x3mor something like that
11:36mi6x3mthen instead of using interpose
11:36mi6x3myou can just do li
11:37mi6x3m(doseq [c (charater...)]
11:37mi6x3m(read-char! c)
11:37mi6x3m(sleep))
11:37mi6x3mthis would make it a bit more readable
11:37fifosinebut then there's an added sleep at the end. This is the purpose of the transpose call
11:39mi6x3mwell you are introducing aritificial complexity right now with all the anonymous functions
11:39mi6x3mso output the first element separately and then the doseq loop
11:43mi6x3mfifosine: something like that, for starters
11:43mi6x3mhttp://pastebin.com/ciLKD9mh
11:43fifosineok, that makes sense, thanks!
11:44mi6x3mfifosine: then you immediately see the pattern for abstraction
11:44mi6x3m1. the function, read-char!
11:44mi6x3m2. the delay
11:44mi6x3m3. the collection, chars
11:45mi6x3mread-with-delay! f d col
12:02justin_smithkqr: hey, have you considered using schema to verify your maps?
12:04kqrjustin_smith, no! what's that?
12:04justin_smithhttps://github.com/Prismatic/schema
12:04justin_smithkqr: it's a lib designed to verify the structure and contents of clojure data
12:04justin_smithwhich sounds perfect for what you are trying to do
12:05justin_smithyou can use it to annotate functions, giving a name to the structure of data it should take or return
12:06kqrthat looks amazing
12:09justin_smithsure beats a bunch of calls to nil?
12:12kqrsure does
13:01fifosine,(doseq [x '((println 1) (println 2))] x)
13:01clojurebotnil
13:02fifosinewhy does that not print?
13:02teslanickBecause it's just a list of symbols.
13:05llasram,(for [x '((println 1) (println 2))] x)
13:05clojurebot((println 1) (println 2))
13:07fifosineteslanick, llasram: I'm trying to write a macro that wraps doseq. I have this so far, but as you pointed out teslanick, it just yields a list of symbols.
13:07fifosine(defmacro wrap-doseq [body] `(doseq [~'x '~body] ~'x))
13:08fifosinehow do I get it to eval?
13:08bbloomfifosine: it seems like you're just using ~ and ' indiscriminately
13:08justin_smithfifosine: the point of doseq is that it do something - but the ~'x in the body won't do anything that the expansion of ~body did not do
13:08bbloomfifosine: it's worth experimenting with ` without defmacro
13:08fifosinebbloom: I might be, I'm using this as an exercise to learn how to use quoting etc
13:08bbloomfifosine: forget macros for a moment and play with the quoting operators in your repl
13:09bbloomfifosine: it will let you iterate much faster and you'll probably figure it out on your own
13:09bbloomand also experiment with x# instead of ~'x
13:09fifosineWhat is x#?
13:09bbloomfifosine: try it in your repl and it should become clear pretty quickly
13:09bbloom(with quoting)
13:10fifosinehow do you mean
13:10bbloomfifosine: you've got a repl right?
13:10fifosineif you could provide a quick example, I'll start experimenting
13:10fifosineyes
13:10justin_smith,`(let [x# 1] x#)
13:10clojurebot(clojure.core/let [x__93__auto__ 1] x__93__auto__)
13:10bbloom,x#
13:10arrdemdoes anyone know of a Clojure java.net.URI wrapper which allows for multimethod dispatch on URI type when attempting to slurp? clojure.java.io doesn't provide this and I'm not seeing it with a quick google.
13:10clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x# in this context, compiling:(NO_SOURCE_PATH:0:0)>
13:10bbloom,'x#
13:10clojurebotx#
13:10bbloom,`x#
13:10clojurebotx__164__auto__
13:10bbloom,'[x# x#]
13:10clojurebot[x# x#]
13:11bbloom,`[x# x#]
13:11clojurebot[x__213__auto__ x__213__auto__]
13:11bbloomthere's like a dozen examples fo ryou
13:11bbloomjust type some crap in to the repl and see what happens!
13:11bbloomyour computer won't explode, i promise
13:15fifosinebbloom: Okay, so I've got the macro working the way I want. It looks like
13:15fifosine(defmacro wrap-doseq [body] `(doseq [x# '~body] (eval x#)))
13:15fifosinebut isn't using eval discouraged?
13:15fifosinehow do I get around this?
13:15bbloomfifosine: quote and eval are (more or less) opposite operations
13:15llasramfifosine: What are you actually trying to make the macro even do?
13:15bbloomthey cancel each other out
13:16bbloomfifosine: so if you've got one too many evals, you might have one too many quotes
13:16fifosinellasram: given a list of unevaluated function calls, wrap it in a doseq (as opposed to a do)
13:16bbloomfifosine: but in this case, you're generating code that has a loop, rather than using a loop to generate code
13:16fifosinebbloom: Yes, that's intended
13:16llasramfifosine: "wrap it in a doseq" isn't well-defined
13:17bbloomfifosine: i think your intention is wrong then :-P
13:17justin_smithalso, '(println :x) is a list of a symbol and a keyword, it is not an unevaluated function call
13:17llasramfifosine: Are you kind trying to re-implement `do` in terms of `doseq`?
13:18fifosinebbloom: actually, you're right, I don't need the doseq to be generated, I could just perform the doseq within the macro
13:18bbloomfifosine: and now it's time to experiment with ~@ outside of defmacro
13:18bbloom,`~@(range 3)
13:18clojurebot#<IllegalStateException java.lang.IllegalStateException: splice not in list>
13:18bbloom,`[~@(range 3)]
13:18clojurebot[0 1 2]
13:18bbloom,`[~@(range 0)]
13:18clojurebot[]
13:18Bronsa`(~@()) :(
13:18Bronsa,`(~@()) :(
13:18clojurebotnil
13:19bbloomBronsa: hmmm
13:19justin_smithBronsa: that last one is like bizarro ascii art
13:19BronsaI should get clojurebot to automatically dec me each time I write clojure code without "," in front of it
13:20Bronsamaybe that'll make me remember
13:20bbloomBronsa: if it could detect that, then it might as well just damn evaluate it :-P
13:20Bronsabbloom: http://dev.clojure.org/jira/browse/CLJ-1444
13:20bbloomBronsa: is that not a giant breaking change?
13:21justin_smithBronsa: add a hook to your client inserting , before all your messages to this channel
13:21justin_smith:P
13:21Bronsa, justin_smith: that might get annoying pretty fast
13:21clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: justin_smith:>
13:21Bronsa^
13:21justin_smithyeah :)
13:22Bronsabbloom: maybe, but I think everybody would expect (~@whatever) to always return a list, not nil
13:22BronsaI doubt there's code that depends on that returning nil
13:22bbloomBronsa: by that logic, i doubt there's code that would desire it to return ()
13:22fifosinebbloom: I have this now, but it still uses eval
13:22fifosine(defmacro wrap-doseq [body] (doseq [x body] (eval x)))
13:23JaniczekHi, is there a way for Schema to throw an exception when I'm using a schema B instead of schema A, but they are the same under the hood? Example code: https://gist.github.com/Janiczek/e9c74130f18dd17c6d11
13:23bbloomfifosine: how come you're still trying to make this work with defmacro? i'm not sure how much clearer i can be about this: get it working without defmacro, using only quoting in your repl
13:24bbloomfifosine: you're confused about both defmacro and quote, so you're definitely not going to understand them both at the same time
13:24Bronsabbloom: find me one guy in this room that knows `(~@x) might return nil (except you and me now) :P
13:24bbloomBronsa: all i'm saying is that i'm sure there's a library somewhere that will break
13:24bbloom:-P
13:24bbloomBronsa: whether or not you care is another question
13:24fifosinebbloom: You're saying, get it working w/out defmacro and without eval, right?
13:24bbloomfifosine: i'm saying forget defmacro until you understand quoting
13:26Bronsabbloom: "For Lists/Vectors/Sets/Maps, syntax-quote establishes a template of the corresponding data structure"
13:26Bronsabbloom: the documentation is clear, if a library breaks, it deserves to.
13:27Bronsabrb dinner
13:27bbloomBronsa: ok, so you don't care :-P
13:27fifosinebbloom: If I understand quoting, should I be able to remove the call to eval in the snippet?
13:28fifosinebbloom: e.g., I still have
13:28fifosine(doseq [x '((println 1) (println 2))] (eval x))
13:28bbloomfifosine: if you understand quoting, you'll understand whether or not you need an eval too
13:28justin_smith,(map #(.getScheme (java.net.URI. %)) ["telnet://foo/bar" "file:///twiddle" "http://example.com&quot;]) ; arrdem maybe I misunderstand your question, but why not use #(.getScheme %) as a dispatch for a multimethod?
13:28clojurebot("telnet" "file" "http")
13:29fifosinebbloom: Ah, okay, I see what you're saying. Well, it seems like if I ever need code to not be evaluated, I need to quote it so that it's known as a list of symbols. If I later need to take that same list of symbols and then evaluate it as I would expect, I have to use eval.
13:30justin_smithfifosine: you can also delay evaluation by constructing a function, and later calling it
13:30bbloomfifosine: except that you don't have to evaluate it yourself
13:30fifosinei.e. if I quote something and then want it evaluated, I need to use eval
13:30bbloomfifosine: a macro takes code in and returns code out
13:30bbloomfifosine: the compiler will ensure that the generated code gets evaluated
13:31fifosinehmmm
13:31bbloomfifosine: like i said, quote and eval cancel each other out
13:32bbloomfifosine: a macro is quoting something, applying a function to it, then evaluating the result of that function call
13:33fifosinebbloom: Given that, I don't think it's possible to write this w/out eval
13:33arrdemjustin_smith: that's what I want to do... issue is that as implemented clojure.java.io doesn't provide such extensible dispatch. URIs are handled as (slurp (.toURL my-uri))
13:33bbloomfifosine: you're wrong
13:33arrdemjustin_smith: pondering how to package such an extension lib
13:34bbloomfifosine: if i give you the answer, you won't get to experience the joyous insight of understanding syntax quote
13:34bbloomfifosine: your goal is to write an expression that returns the right code you want to run, not to actually run the code
13:34fifosineok, don't tell me then, I do want to figure it out I just feel slow
13:35bbloomfifosine: go away and play with your repl, you'll get it
13:35fifosinebbloom: If what I get from defmacro is a list of lists of symbols already quoted, i.e. '((println 1) (println 2)), and I want to iterate over this list, evaling each element, how can I not use eval
13:36bbloomfifosine: why are you still talking about defmacro?
13:37fifosinebecause before, when I assumed not using defmacro, if I wanted to quote things, later I *had* to use eval. as you said, they're "opposite" operations. and then you said "except that you don't have to evaluate it yourself", which I thought was referring to the power of macros
13:37fifosineso then I thought the solution isn't possible w/out them
13:37fifosinebut I guess it is
13:38bbloomfifosine: you don't have to evaluate it yourself when you use defmacro
13:38justin_smithfifosine: he's saying, play with syntax-quote outside macros for a while, see what they really do, then use it inside a macro
13:39bbloomwhich is why i'm advising you to not think about defmacro for a bit, b/c it does some extra operations that make it harder to understand the primitives
13:39bbloomyour goal is to generate the right code, not to run it
13:39bbloomif you want to make sure you generated the right code, you can call eval on that
13:39bbloombut my advice, is to do it like this:
13:39fifosinethen, is there another way of writing this w/out eval and w/out defmacro
13:39fifosine(doseq [x '((println 1) (println 2))] (eval x))
13:39bbloom,'(println 5)
13:39clojurebot(println 5)
13:39fifosineis that what I'm missing?
13:39bbloom,(eval *1)
13:39clojurebot#<Unbound Unbound: #'clojure.core/*1>
13:39bbloomoh, well that would work :-P
13:40bbloomuse (eval *1) to test code you generate in your repl
13:40fifosineI gotcha
13:40bbloomat this point i'm going to stop talking b/c really there's only two ways for you get figure this out 1) somebody tells you or 2) you go experiment for a while and you'll understand it much more deeply
13:41bbloomgo! have fun
13:41fifosineugh ok
13:41fifosineI'm losing sight of the goal
13:44Bronsabbloom: right, I don't care indeed, but my point is that I don't think anybody should care about libraries that depend on behaviour different than that documented
13:44Bronsaabout not breaking*
13:44Bronsathey depend on a bug and bugs should get fixed
13:45bbloomBronsa: i'm just playing devil's advocate here. personally i don't care one way or another, but if you're the only person who has ever noticed, then it's not worth risking any breaking change at all
13:45bbloomBronsa: potentially, anyway
13:46bbloomBronsa: it'd be one thing if no code could break and new code was possible, but somebody might depend on the falseness of that, and you say you don't care, but somebody might be scratching their heads for 3 friggin days after upgrading clojure
13:46Bronsabbloom: that's what changelogs are for :P
13:46bbloomBronsa: you gotta weigh cost & benefit
13:46bbloomcost is potential head scratching & broken lib w/ an absent maintainer
13:46bbloomand benefit is what exactly?
13:47bbloomit matches the "spec" which is a one liner on a page nobody reads?
13:47bbloomdon't get me wrong, i think it probably should return empty list
13:47Bronsabbloom: yeah, I understand what you're saying
13:47bbloomand i'd be totally fine if your patch got accepted
13:47bbloombut then again i'm not a clojure maintainer
13:48Bronsait's just it makes me feel really bad when edge-cases don't work as they should :P
13:48bbloomswitching from devil's advocate to being just a plain old joker:
13:48bbloomyou should go write a programming language with NO EDGE CASES :-)
13:51fifosinebbloom: here's I've been able to write the snippet above w/out eval and w/out defmacro
13:51fifosine(doseq [x '((println 1) (println 2))] (apply (resolve (first x)) (rest x)))
13:51fifosine,(doseq [x '((println 1) (println 2))] (apply (resolve (first x)) (rest x)))
13:51clojurebot1\n2\n
13:52bbloomfifosine: lol well i gotta give you credit, that's creative
13:52fifosineugh, not what you were thinking?
13:52Bronsafifosine: resolve falls into the same category as eval
13:52fifosineaargggggg
13:52Bronsasomewhat
13:52bbloomfifosine: you're still running the code, rather than returning the code that you want to run...
13:53bbloom,(let [x 5] `(* ~x ~x))
13:53clojurebot(clojure.core/* 5 5)
13:53bbloom,(let [x 5] (eval `(* ~x ~x)))
13:53clojurebot25
13:53bbloomfifosine: do you understand the difference between those two?
13:54fifosineyes, the first is returning a list of symbols, the second is evaluating that list
13:54bbloom,(let [form '(prn 1)] (eval `(do ~form ~form))) ; do you understand why this prints two ones?
13:54clojurebot1\n1\n
13:54bbloomcan you write an expression that returns (do (clojure.core/println 1) (clojure.core/println 2)) ?
13:54fifosineyes, ~form turns into (prn 1), then (do (prn 1) (prn 1)) is eval'd
13:55bbloom(eval (doseq [x '((println 1) (println 2))] (apply (resolve (first x)) (rest x)))) ; this is what a macro is going to do to your code
13:55bbloom,(eval (doseq [x '((println 1) (println 2))] (apply (resolve (first x)) (rest x)))) ; this is what a macro is going to do to your code
13:55clojurebot1\n2\n
13:55bbloomthat *looks* like it works, but it's not quite right
13:56bbloom,(def foo (doseq [x '((println 1) (println 2))] (apply (resolve (first x)) (rest x)))) ; let's defer evaluation
13:56clojurebot1\n2\n#'sandbox/foo
13:56bbloom^^ whoops! it evaluated
13:56bbloom,(eval foo)
13:56clojurebotnil
13:56bbloomfifosine: your goal is to produce code which will evaluate correctly, not to evaluate it yourself
13:57bbloomfifosine: experiment with ` and ~@ and replace your doseq with a for
13:57fifosineis for preferrable?
13:58fifosine,(let [x '((println 1) (println 2))] `(do ~@x))
13:58clojurebot(do (println 1) (println 2))
13:58bbloomfifosine: it's different
13:59bbloomfifosine: the reason you're avoiding doseq or avoiding eval is not that there's something wrong with either of them... it's that they don't do what you need them to do....
13:59bbloombut you should experiment with for and doseq and see how they differ
13:59bbloomlook at their source code
13:59bbloomuse eval to understand eval
13:59bbloomand to understand quote
14:00fifosinebbloom: Will I use for to generate code that uses doseq? Or do you suggest replacing doseq with for
14:00Rhainurso I'm a Ruby on Rails dev who's trying to learn Clojure, and I'm having a hard time adjusting to freedom :P Specifically Rails was very heavy on convention, and when I'm developing using Luminus I don't really know where to place my code :(
14:00Rhainurany guides that I can read with regards to this?
14:01bbloomfifosine: can you explain the difference between doseq and for?
14:01Bronsahttps://github.com/clojure/tools.reader/commit/98d04ddce7152f69ac741ec783d0ce577075aef8 I feel kinda better now
14:01fifosinefor will return a list
14:01fifosinedoseq returns nil
14:01bbloomfifosine: and?
14:01fifosinemore specifically, the list returned by for is the concatenation of the results of apply the body to each element in the specified list
14:02bbloomfifosine: doseq also supports concatenating nested loops
14:02bbloom,(doseq [m "abc" n "xyz"] [m n])
14:02clojurebotnil
14:02bbloom,(doseq [m "abc" n "xyz"] (println [m n]))
14:02clojurebot[a x]\n[a y]\n[a z]\n[b x]\n[b y]\n[b z]\n[c x]\n[c y]\n[c z]\n
14:03bbloom(doc doseq)
14:03clojurebot"([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."
14:03fifosineoh ok, like a cartesian product? I didn't know that
14:03bbloomnote the parenthetical:
14:03bbloom"presumably for side-effects"
14:03fifosineto be clear, I'm assuming side-effecful functions
14:03fifosinepart of the reason why i've been using println
14:04bbloomfifosine: if you are writing a macro, your goal is NOT TO RUN THE CODE
14:04bbloomyour goal is to return the code that you want to run
14:04Shoopquick question is there any simpler way to write (for [a seq b seq c seq d seq.........] [a b c d.....])
14:04bbloomfifosine: macros should not have side effects! although the code generated by the macro may have side effects
14:04justin_smith(doc interpose) ; Shoop
14:04clojurebot"([sep coll]); Returns a lazy seq of the elements of coll separated by sep"
14:05bbloomjustin_smith: that's not what Shoop wants
14:05fifosinebbloom: The question I need to answer is, what code do I want to be generated w/out using eval
14:05justin_smithShoop: oh wait, that's for, never mind
14:05BronsaShoop: do you care about the combination order?
14:05ShoopBronsa: not really
14:05fifosinebbloom: and w/out using resolve, I guess
14:06BronsaShoop: then there's `cartesian-product` in math.combinatorics that does exactly that
14:06bbloomfifosine: sorry man, but i kinda give up....
14:06BronsaShoop: https://github.com/clojure/math.combinatorics
14:06ShoopBronsa: thanks :D
14:07bbloom,`(do ~@(for [x '((println 1) (println 2))] x)))
14:07clojurebot(do (println 1) (println 2))
14:07fifosinebbloom: I already have (defmacro wrap-do [body] `(do ~@body))
14:07fifosineI thought that writing it in terms of doseq might be enlightening
14:07bbloomfifosine: i have no idea what you're talking about
14:08alexyakushevHi, quick question. Why the following exception slips through catch: (try (map str 'foo) (catch Exception ex "failed"))
14:08Bronsafifosine: I suggest you read (or re-read) an introductory clojure book or a documentation series before trying to do what you're doing. You clearly haven't understood yet how evaluation & macros work
14:08fifosinebbloom: What I mean to say is, maybe my aim was fruitless. I thought that writing a macro which took a list of function calls, and evaluated the list using doseq as opposed to using do (as above) would be interesting.
14:08fifosinebut I guess it's not
14:09alexyakushevI mean, I know it's probably because of the laziness, but what the hell
14:09Bronsaalexyakushev: yes, it's because of map being lazy
14:10fifosinebbloom: sorry to have wasted your time, but thanks for sticking with me for as long as you did
14:11Bronsaalexyakushev: the only way to make that work is to force the evaluation of map inside the try, with a doall
14:14alexyakushevBronsa: yeap, that's what I thought
14:14alexyakushevSeems awfully surprising and confusing to me
14:16Bronsaalexyakushev: there's no other way to do it and preserve the lazyness of map
14:19alexyakushevBronsa: why the try-catch context cannot be enclosed the same way the closed variables are?
14:22alexyakushevIt doesn't feel good to know that the only Clojure's error handling system will let you down as soon as you call a single sequence-operating function
14:22Bronsaalexyakushev: locals have lexical extent, try-catch blocks have dynamic extent, it's not the same thing
14:23dbaschalexyakushev: what do you mean by let you down? It fails when it’s supposed to
14:23dbaschalexyakushev: it’s the same thing as saying “why does the compiler let me compile code that will fail at runtime?”
14:24Bronsaalexyakushev: it doesn't let you down. if you're using map you should be aware of its lazyness and of the behaviour it implies
14:25alexyakushevdbasch: No, it's not the same. What is the point of an exception that I can't catch? It could just segfault with the same outcome
14:25Bronsaalexyakushev: it's the same for dynamic vars, really, the only difference is that vars being implemented by clojure and not in the jvm, can be "captured" manually
14:26Bronsaalexyakushev: you can catch that exception. you just need to realize the lazy sequence inside the try block instead of outside
14:26dbaschalexyakushev: you can catch it
14:26Bronsa,(try (doall (map str 'foo)) (catch Exception _))
14:26clojurebotBronsa: Huh?
14:26alexyakushevBronsa: point is, everyone's using map. So far the only implied behavior to care about for lazyness were side-effects
14:26Bronsaclojurebot: what.
14:26clojurebotPardon?
14:26alexyakushevBronsa: Clojail is trained to act dumb when it sees a "catch"
14:27dbasch,(try (first (map str 'foo)) (catch Exception ex "failed"))
14:27clojurebotdbasch: Titim gan éirí ort.
14:27alexyakushevsafety reasons I guess
14:27Bronsaalexyakushev: clojurebot doesn't use clojail
14:27dbasch&(try (first (map str 'foo)) (catch Exception ex "failed"))
14:27lazybotjava.lang.SecurityException: You tripped the alarm! catch is bad!
14:27alexyakushevOK, then whatever else it uses
14:27Bronsaalexyakushev: exceptions are not side-effects?
14:28alexyakushevBronsa: I don't see a reason why they should be
14:29Bronsaalexyakushev: it's a side-effect that acts on the state of the program
14:30alexyakushevBronsa: in which way?
14:30Bronsaalexyakushev: anyway, lazyness is not only about side-effects, it's about delayed evaluation
14:31alexyakushevOverall, I wonder what was the point of doing lazy evaluation the default one if a lot of other concepts of the language don't work well with it
14:31alexyakushev"doall your lazy collections to trigger side-effects"
14:31alexyakushev"Don't use dynamic binding with lazy collections"
14:31Bronsalazy evaluation is not the default evaluation strategy
14:32alexyakushevNow it's "doall your lazy collections to handle exceptions properly"
14:32Bronsaclojure is a strictly evaluated language
14:32alexyakushevI don't argue, except that almost all sequence processing library is lazy
14:33alexyakushevI'm trying to find a reason why should I care whether my collections is lazy or not when I want to catch an exception
14:34Bronsaalexyakushev: the evaluation of a lazy collection doesn't imply its realization
14:34Bronsa,(def a (map str 'foo))
14:34clojurebot#'sandbox/a
14:34Bronsayou can't catch the exception caused by evaluation that sequence, if you don't realize it
14:35xeqi,a
14:35clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>
14:35Bronsauntil you realize a lazy sequence, it's just a box with the recipe for building itself
14:36alexyakushevNicola, you are saying everything correctly from the implementation standpoint
14:36Bronsaalexyakushev: if you want to make sure (map f y=[x ..]) succeds assuming that (f x) returns a correct value, you need to validate y
14:37Bronsae.g. (assert (seq y))
14:37alexyakushevBut it doesn't answer the question why can't I have an error handling mechanism that lets me not care whether my collection is lazy or not
14:38alexyakushevOr not a collection at all
14:38justin_smithalexyakushev: do proper validation. the schema library can help there. or you may find yourself happier using a statically typed language. but clojure simply isn't one.
14:40alexyakushevjustin_smith: well, actually I use Clojure exactly for the reason that I don't have to put static types everywhere. I don't want that code to fail during compilation (like it would in statically typed language), I don't want it to fail at all
14:41xeqialexyakushev: what would try/catch do when half the sequence would evaluate successfully?
14:42Bronsaxeqi: he's expecting the try-catch block to be "captured" by the lazy-seq, and its evaluation be done using that try-catch context
14:43Bronsawhich is not something that's really possible on the JVM
14:44alexyakushevBronsa: That's what I "expected", that is right
14:44alexyakushevI'm not saying that's what I really want
14:44Bronsayou'd have to reify every try-catch block and somewhat attach it to its body
14:44alexyakushevI understand that implementing this requires special handling in the compiler, and besides you say it is not at all possible
14:45alexyakushevBut then it means that the current error handling system cannot work well with other primary language concepts (like laziness)
14:46Bronsaalexyakushev: right, that's a tradeoff you're supposed to be making when using lazy sequences
14:47Bronsafeatures that have a dynamic extent like dynamic vars and exception handling don't know how to interact with lazyness
14:47justin_smithlet's remember that with (map str 'foo) the argument isn't even valid - you can use schema validation to catch the error without needing to do anything fancy with try/catch here
14:49alexyakushevjustin_smith: Thank you for trying to put me on the right path, but this is half-artificial example and in my case I actually need the try/catch
14:50Bronsaalexyakushev: (map f x) might fail for two reasons: either x is not seqable or (f y) fails with y an element of x
14:51Bronsaalexyakushev: to avoid the first occurrence, rewrite f as #(try (f %) (catch Exception _ ..))
14:51Bronsato avoid the second, validate x before calling map over it
14:51Bronsathat might involve realizing all, or some part of x, clojure can't do that automatically for you
14:51bbloomBronsa: i've got a compiler question for you
14:52bbloomBronsa: if i return a closure from a method, will that closure keep any pointers to the containing instance?
14:52bbloomBronsa: that is (deftype T [foo] SomeProtocol (someMethod [this] (fn [x] foo))) ; will this be captured at all?
14:53Bronsabbloom: yes if you're using a field of that instance
14:53bbloomBronsa: argh. what if i copy it to a local?
14:55Bronsabbloom: nvm, sorry, it only captures the value
14:55bbloomBronsa: you sure? :-)
14:56Bronsait will capture the instance if you use (.-foo this) rather than foo
14:56bbloomBronsa: ok that makes sense
14:56bbloomthanks
14:56ShoopI am new to clojure coming from an imperative programming background. Can someone help me translate a simple python function into clojure?
14:56Shoophttp://pastebin.com/ezD3bCgv
14:57alexyakushevBronsa: btw speaking of doall, too bad it will help only if you control the sequence generation https://www.refheap.com/89629
14:57gfredericksShoop: depends on how direct you want; lines 13 and 16 aren't very idiomatic, since they're linear time
14:58Bronsaalexyakushev: yeah, doall isn't recursive
14:58Bronsait only forces the sequence you give it, not the subsequences
14:58Shoopgfredericks: i was looking for something more functional
14:58Shoopgfredericks: i tried doing it with recurse but i was having trouble
14:58Shoop*recursion
14:59gfredericksShoop: clojure style usually involves higher level operations on collections when possible
14:59gfredericksShoop: in this case clojure.core/frequencies is an interesting way to get a lot of the logic you have
14:59gfredericks,(def list1 [1 2 3])
14:59clojurebot#'sandbox/list1
14:59gfredericks,(def list2 [3 3 4 5])
14:59clojurebot#'sandbox/list2
14:59gfredericks,(frequencies list1)
14:59clojurebot{1 1, 2 1, 3 1}
15:00gfredericks,(frequencies list2)
15:00clojurebot{3 2, 4 1, 5 1}
15:00Shoopoh and then you could zip them and work from there
15:00gfrederickssorta yeah
15:00gfredericksI would just iterate through the first one and use the second one at each point
15:00Shoopok
15:00Shoopill mess around with that
15:00Shoopthanks
15:00gfredericksnp
15:01gfredericksalso look at map, filter, reduce...
15:01gfrederickswhich work with maps as well
15:01Bronsabbloom: I just checked the bytecode to make sure, I can confirm what I said
15:01alexyakushevBronsa: Yup. So it appears that Clojure pushes laziness down your throat without having the proper infrastructure to deal with its nuances
15:01Shoopok :D
15:01bbloomBronsa: awesome, thank you
15:01bbloomBronsa: working on some fiddly external resource management/cleanup nonsense
15:02alexyakushevWhich probably means that you have to explicitly doall every place you call map/filter/remove if you know you don't need laziness there
15:02Bronsaalexyakushev: if you don't need lazyness, don't use it
15:03Bronsaalexyakushev: I use mapv instead of map when I don't need lazyness
15:03Bronsanow that transducers are a thing, I'll probably use those
15:03gfredericksclojurebot: transducers |are| a thing
15:03clojurebotOk.
15:04alexyakushevBronsa: now that's better. What about filter, can I easily replace it?
15:04gfredericks,(doc filterv)
15:04clojurebot"([pred coll]); Returns a vector of the items in coll for which (pred item) returns true. pred must be free of side-effects."
15:04alexyakushevOK, great
15:05alexyakushevTwo words that could save me an hour of ranting and wasting everyone's time:)
15:05Bronsaalexyakushev: you can use filterv
15:05Bronsa(inc gfredericks)
15:05lazybot⇒ 86
15:05justin_smithShoop: https://www.refheap.com/89630 my imperfect version of example (returns the right results, code could be better)
15:05Bronsaalexyakushev: or, with transducers, use the filter transducer :)
15:06Bronsaalexyakushev: you never said you didn't need the lazyness
15:06Bronsaif you did, I'm sorry I missed that
15:06alexyakushevBronsa: yeah, but I suspect it will take a while before 1.7 will become the oldest supported Clojure version
15:06justin_smithalexyakushev: I don't doubt that people use laziness in clojure without thinking about it, but it is not forced on you - my above function, coincidentially, has no lazy values in it
15:07alexyakushevOr will transducers be somehow backported into 1.5/1.6 (via a library of sorts)?
15:07Bronsaalexyakushev: I doubt they will
15:08alexyakushevBronsa: I might have forgot to say that I don't need laziness in this particular example. But regardless, the map/filter are the functions that you read about in all books, and everyone uses them rather than mapv/filterv
15:08Bronsa,(:added (meta #'mapv))
15:08clojurebot"1.4"
15:08Bronsaalexyakushev: I'll be surprised if books covering clojure >=1.4.0 didn't mention them
15:08alexyakushevI meant transducers when I talked about versions
15:09alexyakushevThey do, I knew about mapv
15:09gfredericksalexyakushev: I missed what your main issue with laziness is; something about error handling?
15:09alexyakushevBut I thought of it more like "map for vectors"
15:09alexyakushevRather than "non-lazy map"
15:10justin_smithgfredericks: the realizing of the lazy sequence can escape a try/catch, and thus not be caught as expected
15:10Shoopthanks justin_smith, looks good. im going to try a version using frequencies as well
15:10gfredericksyeah I guess that is kind of unfortunate
15:10gfredericksyou can't write generic error handling code
15:10justin_smithShoop: the definition of checkout there is a bit verbose - I opted for clarity over conciseness there
15:11gfredericksalexyakushev: I think it takes a bit of concentration wrt the boundaries of your functional vs imperative code
15:11gfredericksthe error handling lives in the imperative part, and you stop using laziness somewhere around the boundary
15:11alexyakushevgfredericks: I'm used to that, just didn't think about error-handling as imperative before
15:11Bronsabtw c.c/iteration is awesome
15:12gfredericksalexyakushev: I probably wouldn't have either except that haskell makes you do it in the IO monad :D
15:12Shoopjustin_smith: well thanks, its very readable :D
15:13Bronsa,(def a (into [] (filter odd?) (map #(doto % println) (range 10))))
15:13clojurebot0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n#'sandbox/a
15:13Bronsa,(def a (into [] (iteration (filter odd?) (map #(doto % println) (range 10)))))
15:13clojurebot0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n#'sandbox/a
15:13Bronsa,(def a (sequence (iteration (filter odd?) (map #(doto % println) (range 10)))))
15:13clojurebot0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n#'sandbox/a
15:14Bronsauhm
15:14hiredman~clojurebot
15:14clojurebotclojurebot is in the Clojure IRC channel. Good work.
15:14hiredman~clojurebot
15:14clojurebotclojurebot is pretty cool
15:14hiredmanhmm
15:14gfredericks~hiredman
15:14clojurebothiredman is an evil genius.
15:14Bronsaclojurebot is not my repl? :)
15:14hiredmanI could be here all day looking for the "is not a benchmarking platform" one
15:15gfredericks~not a benchmarking platform
15:15clojurebotexcusez-moi
15:15hiredman~clojurebot
15:15clojurebotclojurebot is a multimap
15:15hiredman~clojurebot
15:15clojurebotclojurebot queues for elephants
15:15justin_smithclojurebot: benchmark is clojurebot is not a benchmarking platform
15:15clojurebotRoger.
15:15gfredericks~benchmark
15:16clojurebotcriterium or gtfo
15:16hiredmanjustin_smith: you have to wonder, which is did clojurebot take as the assertion there
15:16justin_smithouch
15:16gfredericksclojurebot: forget benchmark |is| clojurebot is not a benchmarking platform
15:16clojurebotI forgot that benchmark is clojurebot is not a benchmarking platform
15:16alexyakushevAll right, thank you Bronsa, justin_smith, gfredericks. I will go and rewrite the code now
15:16hiredmandid it?
15:16alexyakushevbtw, there is no mapcatv, so meh:(
15:17gfredericksalexyakushev: start a library called v
15:17Bronsaalexyakushev: AFAIK there are only mapv filterv and removev
15:17justin_smith(into [] (mapcat ...))
15:17Bronsano removev.
15:17gfredericksIn clojure, the only functions are mapv, filterv, and removev. And there is no removev.
15:18justin_smithgfredericks: worst esoteric lang ever
15:18BronsaI was pretty sure there were 3 $somethingv functions
15:18Bronsameh.
15:18alexyakushevgfredericks: v library — sounds like a plan
15:18alexyakushevAllThingsV
15:18gfredericks,(->> (ns-publics 'clojure.core) keys (filterv #(re-find #"v$" (name %))))
15:18clojurebot[filterv reduce-kv mapv]
15:19justin_smith,(->> (ns-publics 'clojure.core) (map (comp name first)) (filter #(re-matches #".*v$" %)))
15:19clojurebot("filterv" "reduce-kv" "mapv")
15:19justin_smithhah, I had the same thought
15:20gfredericksmine used filterv though which was more in line with the theme
15:20justin_smithheh, good point
15:20justin_smithyours was better expressed all around
15:24Bronsauhm
15:24gfredericks,(defn setv "Like set, but returns a vector" [coll] (vec (set coll)))
15:24clojurebot#'sandbox/setv
15:25dnolen_gfredericks: you tolling? :)
15:25dnolen_s/tolling/trolling
15:25justin_smithdo not ask for whom gfredericks tolls, for he tolls for thee
15:25gfredericksdnolen_: no more than usual
15:25gfredericks~gfredericks
15:25clojurebotgfredericks is a menace to bots everywhere
15:26BronsaI wonder if (sequence (iteration (filter odd?) (range 10))) is supposed to realize the first element
15:27alexyakushevgfredericks: setv goes to the library for sure
15:27alexyakushev(inc gfredericks)
15:27lazybot⇒ 87
15:27gfredericks,(defn incv "Like inc but returns a vector." [x] [(inc x)])
15:27clojurebot#'sandbox/incv
15:28Bronsalol
15:29philandstuffstrv?
15:29alexyakushevlazy-seqv — like lazy-seq but not lazy?
15:29gfredericksthis library is really shaping up
15:29gfrederickslistv
15:30justin_smithvecv
15:30gfredericksnice
15:30gfredericksdoseqv (always returns empty vector)
15:31justin_smithreduce-kvv
15:31alexyakushev(defn shutdown-agents "Like shutdown-agents but returns a vector." [] (shutdown-agents) (vector))
15:31philandstuff,(def emptyv (constantly []))
15:31clojurebot#'sandbox/emptyv
15:31Shoopgfredericks: I think i figured out a way using list comprehensions - (apply + (for [a (frequencies list1), b (frequencies list2) :when (and (= (first a) (first b)) (>= (second a) (second b)))] (second b))))
15:32gfredericksShoop: after calling frequencies you should only have to do one iteration
15:33justin_smithShoop: yeah, that's ignoring the wonderful associative property of a map, but walking it linearly
15:33justin_smithShoop: a little silly
15:33Shoopgfredericks: but testing if the item is in list2 is another iteration
15:34gfredericksShoop: it's a map, so you can do a direct lookup
15:34hiredmanhey, I got JDBC-99, next person to file an issue gets 100
15:34Shoopgfredericks: oh yeah
15:34justin_smith,(reduce + (for [x (range 10) y (range 10)] 1)) ; Shoop
15:34clojurebot100
15:34gfrederickshiredman: oh snap!
15:34justin_smithShoop: for on two collections does a lot my iterations than you might think :)
15:35gfredericksjustin_smith: I think s/he knew that part, just didn't know it could be avoided
15:35justin_smithShoop: frequencies returns a map - you can find out if a key is in a map without iterating
15:35Shoopjustin_smith: its O(n^2) right?
15:35Shoopjustin_smith: yeah i realized that
15:35Shoophe
15:36justin_smith,(get (frequencies "hello world") \l)
15:36clojurebot3
15:36gfredericksgender discovery protocol complete
15:36devnwait... what
15:36justin_smithShoop: I didn't need to walk the map to find that result - it supports directl lookup
15:36bbloomcom.sun.jna.Pointer .... is friggin mutable!
15:36Shoopjustin_smith: i see, well back to the drawing board
15:37gfredericksShoop: want to see mine?
15:37Shoopjustin_smith: its implemented as a hashtree right?
15:37bbloomit just wraps a long and has a frickin static method com.sun.jna.Pointer.nativeValue(Pointer p, long value) to set it
15:37Shoopgfredericks: give me a try, i want to use my brain
15:37justin_smithShoop: a hashmap, which has a few backing datastructures depending on size
15:38ShoopShoop: I thought it was a tree with a branching factor of 32
15:38justin_smith,(type (frequencies "hello world"))
15:38clojurebotclojure.lang.PersistentArrayMap
15:38gfredericksI have no idea what the branching factor on the hashmaps is
15:39Shoopgfredericks: docs say access is log base 32 n
15:39Shoopso
15:39gfrederickswhere does it say that?
15:39ClariceI remember hearing that in a talk some years ago
15:39ClariceIt's based on the implementation of tries
15:40gfredericksnot to be confused with vectors of course
15:40justin_smithShoop: anyway, point is that the datastructure gives us fast lookup, so we should be suspicious if we are walking all the keys unless the point is to do something to every key
15:40ClariceRight, but as far as I can tell pretty much all the basic data types are persistent collections implemented as tries, so that should apply to all of them
15:41gfrederickswell the 32 bit might not
15:41ClariceHas anyone tried Clojure on an Azul machine with great success? I think that'd be a good selling point for them: "Look! Clojure runs super fast with real time garbage collection!"
15:42Shoopjustin_smith: ok let me try again
15:47gfredericksthe number 32 does appear a few times in PersistentHashMap.java, so I'm just going to assume that's right
15:51michaniskini remember seeing a clojure library for data schema validation, but not the prismatic/schema one. does anyone remember what it's called?
15:53mynomotomichaniskin: https://github.com/miner/herbert maybe?
15:53gfredericksalso flatland/schematic
15:54michaniskinmynomoto: i think that's the one! thanks!
15:59Shoopok its not perfect and i can get rid of a bunch of duplicated stuff with let but how is this? (reduce + (for [a (frequencies guess) :when (and (contains? (frequencies code) (first a)) (>= (second a) (get (frequencies code) (first a))))] (get (frequencies code) (first a))))
15:59Shoopoops guess should be list1 and code list2
16:00Shoop(reduce + (for [a (frequencies list1) :when (and (contains? (frequencies list2) (first a)) (>= (second a) (get (frequencies list2) (first a))))] (get (frequencies list2) (first a))))
16:06justin_smithShoop: yeah, a let would help a lot there
16:06Shoopbut i think its down to O(n) now?
16:07gfredericksShoop: I'm not sure that does the same thing?
16:07Shoopjustin_smith: also sorry about the variable name mixup, this is part of a bigger project
16:07gfredericksyour >= filter there seems to be not what you want
16:08Shoopgfredericks: how so?
16:08gfredericksyou want (example [42] [42 42]) to return 1, no?
16:08Shoopyes
16:09gfredericksbut your >= there becomes (>= 1 2)
16:09gfredericksignoring the (first a) at the end which I don't understand at all
16:09gfredericksoh wait nm
16:09Shoopgfrederickks ah
16:09Shoopi see
16:09gfredericksI do understand it but my objection remains :)
16:09Shoopso it should be <=?
16:09gfredericksShoop: I used min for this bit of logic instead of a >= chechk
16:10ShoopCan i see your version?
16:10gfrederickshttps://www.refheap.com/89635
16:12Shoopoh i've never seen ->> before
16:12Shoopthats fancy :D
16:14Shoopgfredericks: btw if you are curious this is for the game http://en.wikipedia.org/wiki/Mastermind_(board_game) if you have ever played it
16:14gfredericksI guessed that by your variable names :)
16:33TimMcI wonder if I sitll have my TI-89 stuff.
16:33TimMcThat calculator is... 18 years old now?
16:36gfredericksI think I transferred them off the calculator once but there's the question of how they're encoded and also where I put the files
16:36justin_smithTimMc: I still have a working tandy 102 - nigh indestructible, those are
16:37gfredericksI got super excited when I learned Java and discovered I could have more than one letter in my variable names
16:37tac_TimMc: and still sold at $100+ to high school students everywhere in the US
16:37Ventac_: and outside of the US, don't worry...
16:37tac_despite having less computational power than an arduino
16:43SagiCZ1are there any timers in clojure?
16:46justin_smithSagiCZ1: there is a Timer class in java you can use with clojure functions via interop
16:47justin_smithpretty simple to use, shown here http://stackoverflow.com/questions/16385049/timers-in-clojure
16:49SagiCZ1justin_smith: i know that class.. ok thanks
16:58ycouyIn core.match, is it possible to match on a variadic "middle" of a collection? So in some way ["foo" xs "qux"] would match ["foo" "bar" "baz" "qux"] and bind xs to ["bar" "baz"].
16:59dnolen_ycouy: not possible
17:00ycouydnolen_: Do you know of any other language or pattern matching library that does this or something similar?
17:01dnolen_ycouy: maybe seqex can do this? https://github.com/jclaggett/seqex
17:02ycouydnolen_: Cool, will look into it. Thanks!
17:15SagiCZ1,(defn foo1 [{x :a y :b]}] (println x y))
17:15clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
17:16SagiCZ1,(defn foo1 [{x :a y :b}] (println x y))
17:16clojurebot#'sandbox/foo1
17:16SagiCZ1(foo1 {:a 5 :b 6})
17:16SagiCZ1,(foo1 {:a 5 :b 6})
17:16clojurebot5 6\n
17:19SagiCZ1,(defn foo1 [{x :a y :b :as a}] (println x y a))
17:19clojurebot#'sandbox/foo1
17:19SagiCZ1,(foo1 {:a 5 :b 6})
17:19clojurebot5 6 {:b 6, :a 5}\n
18:02lavokadhi, I don't find a place explaining why we can create a record using -> ?
18:02llasramlavokad: Example?
18:04lavokad(def algo (->MakeAlgo "lala" "huhu"))
18:05llasramlavokad: One thing `defrecord` does is define a var named `->RecordName`, which is a just a function which happens to start with the characters "->"
18:05llasramIt has nothing to do with the `->` macro
18:05llasramIt also defines `map->RecordName`
18:05lavokadohh
18:08lavokadllasram: thanks
18:10lavokadllasram: where can I find this info? In docs nothing about this appears
18:14lavokadall right I found this in the source code :)
18:15llasramlavokad: It's mentioned in the last paragraph of the `defrecord` docstring
18:16gfredericks,(-> defrecord meta :doc (clojure.string/split #"\n\n") last)
18:16clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/defrecord, compiling:(NO_SOURCE_PATH:0:0)>
18:17gfredericks,(-> defrecord var meta :doc (clojure.string/split #"\n\n") last)
18:17clojurebot" Given (defrecord TypeName ...), two factory functions will be\n defined: ->TypeName, taking positional parameters for the fields,\n and map->TypeName, taking a map of keywords to field values."
18:17llasramgfredericks: Nice
18:17llasram(inc gfredericks)
18:17lazybot⇒ 88
18:24lavokad(doc defrecord)
18:24clojurebot"([name [& fields] & opts+specs]); (defrecord name [fields*] options* specs*) Currently there are no options. Each spec consists of a protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args*] body)* Dynamically generates compiled bytecode for class with the given name, in a package with the same name as the current namespace, the given fields, and, optionall
18:25gfredericksI love that the first sentence is "Currently there are no options."
18:26lavokadwhy does the same doc info of defrecord appear on the web?
18:27gfrederickswhy not?
18:28lavokadi mean doesnt, sorry
18:28gfredericks$google "Currently there are no options"
18:28lazybot[ClojureDocs - clojure.core/reify] http://clojuredocs.org/clojure_core/1.2.0/clojure.core/reify
18:28gfrederickshaha
18:28justin_smith"You're viewing version 1.2.0 of reify. The latest stable version of Clojure Core is 1.3.0."
18:28justin_smithlol
18:29lavokadhttp://clojuredocs.org/clojure_core/clojure.core/defrecord is not equal to (doc defrecord) output
18:30justin_smithlavokad: that's the 1.3 version of the docs
18:30justin_smith&*clojure-version*
18:30lazybot⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}
18:30justin_smith,*clojure-version*
18:30clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
18:30TheMonarcwhat are the maiun reasons one might use clojure over other langs?
18:31lavokadgoshh
18:31lavokadsorry
18:31lavokadthanks
18:31lavokad:)
18:31justin_smithlavokad: it's sad that the clojuredocs site has so much google-juice, and is so out of date
18:33llasramTheMonarc: My reasons: it runs on the JVM and provides high developer productivity
18:33gfredericksTheMonarc: lets you write pure functions on generic data and then use them in real life
18:35hyPiRion_Efficient immutable data structures, and powerful functions to manipulate them.
18:36justin_smitha stable and predictable runtime that will be identical to your local development environment without needing all sorts of fashionable tooling
18:37TheMonarcexample of "fashionable tooling" from another stack/lang?
18:38justin_smithdocker, puppet, chef
18:38justin_smithvarious ways to try to automate the duplication of environments in production, that we typically just have no need for
18:38TheMonarcaren't those things orthogonal to language/VM choice
18:39justin_smithTheMonarc: I deploy servers that run if you have a jvm of 1.6 or newer
18:39TheMonarcBTW, i'm not a java developer either so excuse me if my questions are ignorant
18:39TheMonarcwhat if you have project that requires java version X
18:39TheMonarcand then another project that requires java version Y
18:39justin_smithTheMonarc: literally any machine meeting that spec suffices - you don't need much automation to make that work
18:39TheMonarcwouldn't someting like docker help w/ that?
18:39llasramjustin_smith: I take issue with your terminology :-)
18:39justin_smithTheMonarc: java version x or newer is a trivial dep
18:40TheMonarcbut X and Y are different
18:40TheMonarcwouldn't docker help switch back and forth between an environment where X is met, and one where Y is met?
18:41justin_smithTheMonarc: you can use the newer one - it really works that way
18:41TheMonarcjustin, are you saying that specifically with Clojure
18:41amalloyjava very very very rarely breaks backwards compatibility
18:41TheMonarcor just for Java in general
18:41llasramTheMonarc: Yeah, I can't really reflect justin_smith here. In my experience it's about the same as deploying software in other languages
18:41llasramI do think that the Java/Maven packaging and dependency systems ends up being somewhat better than almost everything else
18:42llasramBut AFAICT packaging is something no-one ever gets completely right :-(
18:43justin_smithllasram: we may be trying to do different things. I have never ended up needing a setup more complex than "jvm v. x or newer" *(plus a reverse proxy, which every language needs)
18:43justin_smithfor a webapp that is
18:44TheMonarcany recommendations on a noob to get started with clojure?
18:45TheMonarclike what should i do once I do "Hello World" in clojure?
18:45justin_smith~books
18:45clojurebotbooks is http://clojurebook.com/ http://joyofclojure.com/
18:46bounbTheMonarc: i am a clojure novice working thru clojurebook.com and i recommend it
18:46justin_smithTheMonarc: I also like aphyr's clojure from the ground up series http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome
18:46bounbit will answer your question "why clojure" at the start too
18:46devnout of curiosity, does anyone here use slime still?
18:47justin_smithiirc amalloy does
18:47devnis it usable anymore?
18:47amalloydevn: works fine
18:47devnbecause, and i seriously mean no offense here, i think i preferred it way more
18:47llasramjustin_smith: Mine isn't that much more complicated, but I find having a version-controlled, executable, repeatable description of the full deployment utterly invaluable
18:47devnamalloy: do you by any chance have a gist of the relevant config laying around?
18:47amalloydevn: {:plugins [[lein-swank "1.4.5"]]}
18:48devnamalloy: yeah, was referring to emacs
18:48justin_smithdevn: there were some really cool things about slime that I missed. The complaint I seem to remember was that the underlying slime was a fast moving and often breaking target, but I don't see any major improvement on that in cider.
18:48amalloywhat relevant config?
18:49amalloyjustin_smith: lein-swank uses a four-year-old snapshot of slime, works fine. definitely not fast-moving
18:49devnamalloy: i remember back in the day having to set a bunch of things up to get everything working
18:50amalloywell
18:50devnamalloy: what do you have in your emacs config related to slime/swank? and you just mentioned the other question: what packages do you have? do you install slime from marmalade? slime-repl? slime-clj?
18:50amalloyyou probably have to do some, but not actually that much. i don't really know; i've just copied around the files i installed four years ago
18:50devnim just looking for the: "this is the absolute minimum required to jump back to lein-swank" story
18:51devnamalloy: lol yeah, that's basically what im asking for -- would you mind gisting what you're using?
18:51amalloydevn: clone git@github.com:amalloy/clojure-mode and add it to your load-path, and then (require 'clojure-mode). i think it gets a version of slime from lein-swank
18:52devnamalloy: oh, and the more recent version of clojure mode brings in nrepl or cider or something?
18:52amalloymaybe
18:52justin_smithdevn: I think the newer clojure mode is agnostic to the repl integration
18:52justin_smithdevn: for example I require both clojure-mode and nrepl
18:52amalloy(setq clojure-swank-command "lein with-profile +swank jack-in %s") is good too, so that you can have {:swank {:dependencies ...}} in your project.clj
18:52devni have a brand new computer sitting in front of me. i was carrying around emacs config for years and i recently blew it all away
18:53justin_smith(I still have not made the cider plunge)
18:53devnotherwise i wouldn't bother you
18:53TheMonarcoh and tell me about repl
18:53TheMonarcin a nutshell
18:53TheMonarci keep reading people mentioning REPL
18:53TheMonarcin terms of haskell, scala, and clojure
18:53devnTheMonarc: yessir! the repl dude! it's awesome!
18:54amalloydevn: you can see my .emacs and .emacs.d at github.com/amalloy/dotfiles, but i don't promise that they're clean and easy to read
18:54TheMonarcbut what exactly is it
18:54TheMonarcand why do people rave about it so much
18:54justin_smithTheMonarc: clojure is designed such that everything you can do in clojure (with very few exceptions) can be done in the interactive interpreter (the repl)
18:54devnTheMonarc: REPL stands for Read Eval Print Loop.
18:54amalloybetween that, my clojure-mode, and .lein/profiles.clj, that's all i *know* i have set up. there may be some old packages lying around, and if so sorry
18:54devnamalloy: thanks
18:54TheMonarcok so kind of like the scheme interpreter we used in school
18:54TheMonarcDr. Scheme
18:54devnamalloy: that's no problem. thanks much
18:54justin_smithTheMonarc: right, that is also a repl
18:55devnTheMonarc: yeah, so im going to attempt to convey what i believe to be the "right" way to develop clojure
18:55devnbut some people don't do this
18:55justin_smithbut clojure's repl is technically not an interpreter, it compiles code as it goes
18:55TheMonarck, i'm all ears
18:55devnTheMonarc: let's say you're in your editor, and you're in a file: src/hello_world/core.clj
18:56amalloyjustin_smith: IMO that's an implementation details: as far as a user can observe, it's an interpreter
18:56devnso inside of there you have (ns hello-world.core (:require [clojure.string :as str]))
18:56devnand you have (defn hello [name] (println (format "Hello, %s" name)))
18:56devnyou "connect" or "jack in" to your project
18:57devnand then you can evaluate (and re-evaluate) chunks inside of that file
18:57devnso first you might want to evaluate the ns declaration at the top. so you do that, and it returns nil. cool. then you evaluate your hello function
18:57devnbut it turns out you didn't quite like it, so you change some stuff inside of it, and evaluate it again from your editor
18:58TheMonarcok that sounds pretty cool
18:58devnit's very playgroundish
18:58TheMonarcone more question for now
18:58TheMonarcany IDE's or editors recommended for use with Clojure?
18:58devnive seen people doing clojure who dont really use the REPL to their advantage
18:58devninstead they run the whole program every time
18:59justin_smithmy development is more directly repl-centric, where I experiment with code in the user ns in the repl until I have the basic structure, then adapt that into my individual namespace
18:59devnthat's backwards in clojure IMO
18:59bounbdevn: how does one 'connect' or 'jack in'
18:59devnbounb: what editor are you using?
18:59bounbvim
18:59TheMonarcdevn, is there an article that describes how you use the REPL?
18:59squidzdevn: clojure or clojurescript?
18:59justin_smithbounb: you can use fireplace for connecting vim to a repl
18:59devnTheMonarc: no, but i could show you if you want to do a google hangout
18:59devnsquidz: clojure
19:00TheMonarci'd like to get back to it and make sure i'm getting the most out of the REPL once i get through some hello world and other basic/intro stuff
19:00bounbjustin_smith: nice, thx
19:00TheMonarc@devn, ah, i'm not at the point where i'm ready to do that yet
19:00devnclojurescript is harder
19:00devnbut you can stil use the REPL
19:00devnbounb: https://github.com/tpope/vim-fireplace
19:00bounbtpope ✓
19:00amalloyTheMonarc: whatever editor you're using probably has reasonable clojure support. but you might just do the primitive copy/paste from your editor to your repl for a while; it's not critical to get editor support set up until you're familiar with the language and a repl
19:00devn"There's a REPL in fireplace, but you probably wouldn't have noticed if I hadn't told you. Such is the way with fireplace.vim. By the way, this plugin is for Clojure.
19:00devn:)
19:00justin_smithTheMonarc: also, regarding your "what are good reasons to use clojure" survey question, now I am wondering what the bad reasons to use clojure are.
19:00bounbdevn: thx
19:01TheMonarcbecause hipster
19:01bounbnot at all
19:01bounbTheMonarc: what is your programming backgroun
19:01bounbd
19:02TheMonarcor do you mean what are the bad use cases for Clojure?
19:02devnlighttable has a really great setup by default
19:02devnyou should try it out
19:02TheMonarci code in C#
19:02TheMonarci hate my current job
19:02devnTheMonarc: lol. it's going to be ok!
19:02devnyou're here. that's all that matters. :)
19:02TheMonarchahah
19:02TheMonarcyeah planning on branching out with various langs
19:03TheMonarcright now exploring scala and clojure
19:03devnclojure is a good train to get on. scala is...
19:03devnscala is...
19:03TheMonarci figure i will touch on the JVM langs all together
19:03devnpoorly designed.
19:03bounbit's not directly about clojure and the question "why clojure" is answered more succinctly in clojurebook.com but i think everyone (TheMonarc) should watch this great talk http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
19:03devnamen bounb
19:03bounbjust watched it earlier and was pretty blown away
19:03TheMonarcthanks for that recommendation
19:03TheMonarcadding it to my list
19:03devnthat is THE talk. everyone needs to watch that talk. i think i watched it a dozen times when i first started getting into clojure
19:04TheMonarcspending this entire weekend watching programming vids and doing tutorials
19:04devnseriously TheMonarc -- sit down and watch it. it explains a lot of the Why?
19:04bounb<- starting to get into clojure ;)
19:04bounbyeah it's one of the best programming talks ive seen tbh, very... philosophically complete
19:05devnRich's talks are all fantastic. The one post I ever wrote for the changelog: http://thechangelog.com/rich-hickeys-greatest-hits/
19:05devnturned out to be the hottest post of the year and then i never wrote another
19:05devnim a terrible blogger.
19:05TheMonarcme too
19:05bounbhaha nice yeah i saw this list earlier ill check out the rest!
19:05TheMonarci have more blog entries in my drafts folder
19:05TheMonarcthan i have actual publish posts
19:06TheMonarcdo you guys use clojure at work?
19:06devnyes
19:06TheMonarcone of the reasons i'm gravitating towards clojure/scala
19:07TheMonarcand correct me if this impression si wrong
19:07devnalmost 100% clojure, maybe 2% nodejs and ruby which will be rewritten soonish
19:07TheMonarcbut ideally i'd get a job where those langs are being used in production apps
19:07TheMonarcand i feel like the caliber of developer working with those langs
19:07TheMonarcis going to be much higher than the C# dev's i interact with every day
19:07TheMonarc(there are some really good C# developers out there, but none of them are in the network of people i come across in my day job)
19:07devnTheMonarc: i know that i dont need to say it, but the following is just my opinion: dont waste your time with scala
19:08devnscala is a terrible language IMO
19:08TheMonarchaha
19:08TheMonarcwell for now i'm at least going to expose myself to it
19:08TheMonarci want to keep an open mind
19:08devnyeah, totaly fair
19:08Wild_CatTheMonarc: it's kind of the same reasoning as that behind choosing to work in Python. In many cases, it's true
19:08Wild_Cat(although with Python it's becoming less so these days as it enters the mainstream)
19:09devni dont know a ton about scala, but i know plenty to know that there's no way i'd ever want to seriously work with
19:09TheMonarcwait so what's so bad about scala?
19:09devnhaha, oh gosh
19:09Wild_Catbecause nobody just knows Clojure because it's what they learned at uni and/or their first job and couldn't be bothered to try something else
19:09TheMonarceven when i went onto #scala, i asked people if they used it at work and one guy went off on a rant about how much scala was an "illusion"
19:09Wild_Cat(whereas you just have to kick a trash can a couple times and J2EE/PHP developers fall out)
19:10TheMonarcwhich was ironic given that i was in the #scala channel
19:10devnTheMonarc: here's an example of the crazy shit they've done... i was talking with a JVM developer who told me that Scala's implementation of Value Classes causes 6^9 class files to be generated
19:10devnand that the reason why SBT (build tool) is so slow is because of I/O
19:10TheMonarcwow
19:10Wild_Cato.O
19:11bounblol...
19:11devnand worse
19:11devntheir value class implementation still doesn't really solve the deeper problem on the JVM
19:11devnit doesn't really add them
19:11devnit's like a thin veneer of value classes
19:12devnbut anyway, more evidence that scala is a bummer: gah, trying to find the video
19:13devnbasically one of the co-founders of typesafe and a massive contributor to Scala. like 900+ closed issues. 500 issues filed.
19:13Wild_Catthe damning evidence against Scala is that I've heard *Haskell* developers complain that Scala's type system is scary.
19:13devndecided that scala is horribly broken
19:13devnand he left typesafe
19:13bounbu guys fans of haskell?
19:14bounbive started learning it... a few times haha
19:14devnsure, im a fan. there's tons to learn in haskell land.
19:14devni find the clojure crew a much more pragmatic bunch
19:14TheMonarcany of you tried F#?
19:15devni also find the people in the clojure community to be a lot more helpful, friendly, nice overall, less prone to pissing contests
19:15Wild_Catbounb: it's a fantastically elegant language, with tons of excellent ideas. No language I've ever touched has changed the way I think about programming in general as Haskell.
19:15bounb:)
19:15Wild_Catnonetheless, I've never used it in a real project and probably never will.
19:15bounbi see yeah
19:15TheMonarcthe guy that writes the Clojure Gazette worked in haskell for a couple of years
19:15Wild_CatI find Clojure far more pragmatic, and on the "smart type system" side of the spectrum it's actually Rust I want to learn.
19:15devnyeah, same her
19:16devnhere*
19:16TheMonarche didn't seem that thrilled by using Haskell
19:16Wild_Cat(as for my day job, Python all day every day with some C++ here and there)
19:16devndevops?
19:16bounbpython is where i'm comfortable but it's boring
19:16Wild_Catdevn: no, backend for game development.
19:17devnpython is a decent language. i like python. the `python -c "import this"` Zen of Python matches pretty well with Clojure's general philosophy
19:17TheMonarcdo you have any personal strategies for learning new langs
19:17Wild_Cat(previously casual Facebook games in the 500K DAU range, now AAA)
19:17TheMonarclike do you just work on it when you get a chance and depend on your personal drive to get you to do it
19:17amalloyTheMonarc: one i've heard recommended is to have a "pet project", which you implement in each new language you want to learn
19:17devnTheMonarc: yeah, id do some problems on project euler and 4clojure
19:17TheMonarcor do you force yourself to work a certain # of hours per day or week or whatever
19:17Wild_CatTheMonarc: find something you want to do, and implement it in the language you want to learn rather than in the one you know.
19:17amalloythen you're familiar with the problem space enough that you can focus on what's new about the language
19:18TheMonarcamalloy, interesting, i've been thinking of doing exactly that
19:18Wild_Cateven better if you can do it at work, but don't go too exotic in that case. People will hate you when they need to maintain your app written in Coq.
19:18TheMonarcin my head i call it my "Rosetta Stone Project"
19:18TheMonarcthat i would implement in each lang
19:18devnbut also what Wild_Cat said -- after you do a couple of basic things, pick something that's more like a project
19:18TheMonarcwild_cat, lol, yeah
19:18devnlike writing an IRC bot or building a static site generator or a blog or something
19:18TheMonarci know better than to burden coworkers with exotic stuff
19:19devnTheMonarc: i dont want to tell you i know for a fact what you're going through, but i was in what sounds like a similar position about 7 years ago
19:19Wild_Catfor example, the current micro-project I'm working on at work is something I'm currently writing in Python with Gevent and Pyramid (and Redis, which makes me learn more Redis and Redis is awesome), but I'll probably try a Rust rewrite at some point.
19:19devni finally just quit with no plans
19:19amalloyTheMonarc: when i was still newish to clojure, i was working in php; i found it useful to sketch out in clojure the new stuff i needed to write in php, because the repl speeds things up so much. it probably helped me learn both languages
19:19Wild_Cat(e.g. if performance becomes a true issue, which I doubt it will)
19:20TheMonarcso i'll just need to decide on a project
19:20devnamalloy: yeah, that's a good point. i was doing a lot of ruby around the time i picked up clojure. i found that building up a table of | clojure function | ruby method | was helpful
19:20Wild_Catalso, I find DBs are as important to learn as languages.
19:21devni also found that it made my ruby code a lot better
19:21Wild_Catlearn Mongo, learn Redis, learn a SQL database.
19:21TheMonarcyup
19:21TheMonarci have a big ass list of stuff to learn
19:21devnbooooo mongo :D
19:21TheMonarcrabbitmq is high up there
19:21devnpostgres, rabbitmq
19:21amalloyTheMonarc: you could write a scheme interpreter. it's small enough, and i think you said you learned scheme at school
19:21TheMonarci want to introduce it at work, which is stupid because we already have it one one project at work
19:21amalloybut of course if that doesn't interest you, do something else
19:21TheMonarcbut the douchebag architect hides it from everyone
19:22TheMonarcliterally, won't let anyone use it, so it's just sitting there being used by a single process, which kind of defeats the point
19:22devnTheMonarc: one thing i found really interesting when i came to clojure was metadata, and there are some fun exploratory projects you can do there
19:22gfredericksclojurebot: rabbitmq is hidden from everyone by the douchebag architect
19:22clojurebotIn Ordnung
19:22devn,(map (comp meta second) (ns-publics 'clojure.core))
19:22clojurebot({:ns #<Namespace clojure.core>, :name primitives-classnames, :file "clojure/core_print.clj", :column 1, :line 315} {:added "1.0", :ns #<Namespace clojure.core>, :name +', :file "clojure/core.clj", :inline-arities #<core$_GT_1_QMARK_ clojure.core$_GT_1_QMARK_@180023a>, ...} {:ns #<Namespace clojure.core>, :name decimal?, :added "1.0", :file "clojure/core.clj", :static true, ...} {:ns #<Namespace c...
19:22Wild_Catdevn: I really don't get the Mongo hate. It works.
19:23devnWild_Cat: for small problems, yes
19:23Wild_Catheck, I could spew way more hate on MySQL than on Mongo, because I've had real bad issues with the former.
19:23TheMonarci prototyped a project in mongo
19:23p_lWild_Cat: Well... you're comparing similar quality there
19:23TheMonarcand it was pretty easy and nice to use
19:23Wild_Catdevn: my previous company's biggest game uses Mongo and it's a breeze.
19:23TheMonarcbut any documentDB would have been just as good in my case
19:24p_lTheMonarc: that's about main pros of Mongo I've ever seen have substance...
19:24TheMonarca lot of the complaints about mongo i've seen have been people's own fault of using a documentdb when they really needed something else
19:24devnmy experience has been: for quick things where i dont want to configure stuff and just start using a store, mongo is nice.
19:25devnonce you start getting to the point of having a mongo cluster
19:25devnall hell begins to break loose
19:26TheMonarcyeah i'd be wary of any scenario that needed a cluster
19:26TheMonarcsharded at least
19:26TheMonarcif it was just replicated i guess that'd be fine
19:26p_lit's the same code and behaviour...
19:26TheMonarci'd ha ve to do research before committing to mongo for something that needed a cluster though
19:26devnwell, it's not a problem for other document stores
19:27devnive heard good things about couch
19:27p_l(and some people caught Mongo dropping writes at load, which lead to funny things)
19:28TheMonarcdevn, you mentione dyou use clojure at work
19:28TheMonarcwhat kind of stuff? web app(s)?
19:28devnyeah
19:29devnservices and apps
19:29TheMonarccool
19:29devnlots of clojurescript too
19:29TheMonarcnice
19:29TheMonarcdo you do SOA/microservices?
19:29Wild_Catfun fact, said game actually uses a Mongo cluster
19:30Wild_Catit works trivially because players are essentially isolated from each other, which means we do massive numbers of extremely simple DB operations.
19:31devnTheMonarc: some "microservices" sure. i suppose it'd also be fair to just call them "appropriately sized services"
19:31TheMonarchaha
19:31TheMonarcyeah i've been reading about it the past week, and there doesn't seem to be a real definition
19:31devneverything is a microservice when you compare them to the services of old
19:31TheMonarcother than that they are "small"
19:31TheMonarci never got into SOA, so i don't know if this distinction is correct
19:32TheMonarcbut it seems when people talk about microservices
19:32TheMonarcthere is also tendency to have all these services be called directly from an edge/front end system
19:32Wild_CatTheMonarc: I think what people mean by "microservices" is actually "not SOAP. Anything but SOAP. Oh god, never again SOAP."
19:32devnTheMonarc: there are a lot of opinions, but just like anything else -- there are tradeoffs.
19:32TheMonarci keep wondering how are you not running into latency issues
19:32TheMonarctimeouts etc
19:33TheMonarcwas that also an issue with SOA?
19:33devnmicroservices are great until you need to start coordinating sweeping changes across 10s of them
19:33devnbut maybe you already thought that through ahead of time and so it's not a big deal
19:33TheMonarc@wild_cat LOL
19:34devnmicroservices make a lot of sense at first glance i think. they forcefully decouple code. they potentially allow you to scale out critical services cheaper because you can just get lots of small EC2 instances instead of needing monolithic server horsepower
19:35devnbut once you have 100 EC2 instances for some service, you need to coordinate them
19:35TheMonarc100 EC2 instances...
19:35Wild_Catmicroservices make a lot of sense architecturally when you decide to write your app as something that needs to easily scale up by spinning up new VMs in a cloud somewhere.
19:36TheMonarcseems like a lot
19:36devnim not being down on them. i think it's a great idea. it's not really a new idea either.
19:36Wild_Cat...and once you start needing them to coordinate somehow, you need to involve a message queue or something similar.
19:36devnTheMonarc: heh, that's not much
19:36Wild_Catbecause any other approach leads to madness.
19:36TheMonarcwildcat
19:37TheMonarcgive an example of when you need to "coordinate"
19:37TheMonarcthe instances
19:37TheMonarcdo you mean put a piece of async work into a queue
19:37Wild_Catmost of the time, yes
19:37TheMonarcfor a separate service to process?
19:37devn"we're overloading another service. everyone who is a service like me, slow down!"
19:38TheMonarcah ok
19:38TheMonarcso a circuit breaker across all instances of Service A
19:38TheMonarcso they don't overload service B
19:38devnit's a simple example sure
19:39devnhere's the thing. let's say you have 50 microservices. and some of those services talk to other services, who talk to other services
19:39TheMonarci never had to implement something like that
19:39devndraw the graph
19:39TheMonarcbut i imagined if i did, my naive approach would be to use a reddis cache or something to store state that Service A instances would use
19:39devnnow tell me: do you think it will be more difficult to make changes?
19:39TheMonarcrather than a queue
19:40TheMonarcdevn, yeah it seems like it'd be difficult to make changes
19:40devnif you change service A, and service B uses service A through Service C, and Service C uses Service B, and Service D uses B, and so on...
19:40devnyou need to have that story figured out early on
19:40TheMonarcmy thought on that
19:40TheMonarcwas you could version the services
19:40TheMonarcso at the bottom of the graph (the nodes that everything else depends on), you deploy two versions side by side
19:41TheMonarckeep doing that "up" the graph till new stuff is all deployed
19:41TheMonarcthen retire the old versions
19:41devngreat, but now what does it take for you to do a release?
19:41TheMonarcprobably a lot of problems with that approach though
19:41devntakes you forever now to get a deploy out
19:41TheMonarcso how do you sole that
19:42devncarefully ;)
19:42devnthere are lots of things you could do, right?
19:43devnyou could make logical groups of services which will depend on nothing but a single interface to another group of services
19:43devnsort of like organs in the body
19:44devnyou could do as you're saying and actually keep legacy services online and transition them out
19:45TheMonarcand you should only have to do the side-by-side-and-then-transition-out thing when a service has a breaking change right?
19:45devnyou could send your version over the wire to other services to tell them: "Hey! I'm newer than you!"
19:45devnor "I'm older!" so you can get the response you expect
19:46devnTheMonarc: well this is the thing, and this is why simulation testing is important
19:46devnif you have a really complex graph of microservices
19:46devnyou need to be able to replay production traffic and simulate traffic so you can find out who talks to who
19:46devnbcause it changes often
19:48devnand make sure that everyone knows how to live in the "my microservice just got a tiny version bump and now everyone has to deal with it" world
19:48joobusdoes anyone here use the nginx-clojure module?
19:49devni haven't
19:49Wild_Catdevn: as someone who's currently living in the "we refuse to upgrade from a 4-year-old version of MySQL that you can crash with a very simple query" world, that world you describe is tempting.
19:49devnWild_Cat: it comes with its own set of problems though, yknow?
19:49devnthe grass is always greener.
19:49Wild_Catindeed.
19:50devnRAPID DEPLOY! GO GO GO! ... Oh wait, we need to manage this now...
19:50devnvs 4 years of QA
19:50joobusi've been reading the install tutorial but it's written in broken english...
19:50devnjoobus: nginx is a product of russia after all :)
19:50Wild_Catyeah, it's a tradeoff of "crap, it's broken!" vs "crap, it's still not fixed!"
19:50devnWild_Cat: i prefer the middle
19:51Wild_Cathence 'tradeoff' ;)
19:51devn"it's still not fixed because we will all have to coordinate" and "crap it's broken, but we knew about it when <1% of traffic was being passed through the new production environment"
19:52justin_smithdevn: is there a SO like site for that kind of architecture / system design stuff (and better yet, also intersecting with the programming and implementation side)
19:52TheMonarcyeah i wish i had to deal with this kind of problem at work
19:52joobusyou guys have time to do qa?!?! my company does QA if we have time...
19:52devnjustin_smith: i dont really know much about the SO ecosystem
19:52amalloyjustin_smith: probably serverfault
19:52devnjoobus: QA has the word "assurance" in it, which makes it kind of a funny term to begin with
19:53devn"intended to give confidence"
19:53justin_smithamalloy: I thought that was more for administrators than designers - but maybe that crosses over more than I thought
19:53TheMonarcyeah serverfault is for like "how do i configure IIS to enable gzip compression" type questions
19:53devnQA means a lot of different things to a lot of different people
19:54amalloyprogrammers and SO probably fit too; between the three of them you should be able to ask most any question about this kind of stuff. but i haven't really tried
19:54devn"it isn't on fire." vs "i noticed that when we give this 2x the load we normally have in production it falls over."
19:54devnanyone have any experience with CQRS?
19:55joobusmy comp uses python, so we don't see the error until someone hits that path.
19:55TheMonarcnone of the microservices blog posts/articles i've read have really gone into any detail about how they handle the versioning scenarios that devn mentions
19:56devnthat's because it's kind of buzzwordy IMO
19:56TheMonarcis that because the options are all messy/bad and no one wants to acknowledge it?
19:56devni've seen a couple of posts (would have to dig them up from history)
19:56devnabout "well, we tried, and we sort of got it right... but..."
19:57devnwell some of it is kind of just...idk, trendy.
19:58TheMonarccurrently have this article about CQRS in my open browser tabs: http://www.udidahan.com/2009/12/09/clarified-cqrs/
19:58TheMonarcbut i haven't done CQRS
20:03devn_go strmpnk___
20:03devn_whoops
20:03joobuswho here uses clojure professionally?
20:04justin_smithI do
20:05joobusdo you work for a startup?
20:05joobusjust wondering how much penetration clojure is getting in the "real world"
20:05devni use clojure at work
20:06devnjoobus: ive been around this community since pre 1.0 days and it is growing big time
20:06justin_smithjoobus: not a startup - I have a contract with a digital agency supporting some sites I developed for them. Previously was salaried doing clojure for web site backends.
20:06devni mean, the fact that wal mart labs and staples labs were at clojure west should tell you something
20:06joobusI've been tinkering for about a month now
20:07devnjoobus: http://www.indeed.com/jobtrends?q=ruby%2Cjava%2Cscala%2Cclojure&amp;relative=1&amp;relative=1
20:08TheMonarchttp://www.indeed.com/jobtrends?q=scala%2Cclojure&amp;l=
20:09devnif you're just looking for a job with a different JVM language, Scala is a choice
20:09devnif you want to be a happy human being who enjoys their work, clojure
20:09devn;)
20:10TEttingerjoobus, clojure is very startup-friendly, since an experienced dev can get an app up and running with a good deal less code than, say, Java. but there's also the advantage of being able to interop with existing Java codebases which is great for established companies that use Java too. I'm speaking in generalities and of course every company will have different needs, but clojure's strengths are aimed at being a business-friendly lisp
20:10TheMonarcwhat do you do for web/service frameworks with clojre
20:10devnjoobus: TheMonarc: https://github.com/Dobiasd/programming-language-subreddits-and-their-choice-of-words
20:10TheMonarcdo people use clojure specific frameworks
20:11joobusI currently don't have a JVM language in my toolset, nor a functional lang. I began looking into clojure on the recommendation of a friend using clojure at a startup
20:11devnhttps://github.com/Dobiasd/programming-language-subreddits-and-their-choice-of-words/raw/master/img/happy.png
20:11TheMonarcor do you use Spring/Dropwizard etc
20:11TheMonarcwith clojure?
20:11devnTheMonarc: most people don't use "frameworks"
20:11devnthe idea in clojure is -- libraries > frameworks
20:11devncompose your libraries and you can have your own framework
20:11TheMonarc@devn, nice
20:11devnthere are some pretty common pieces in that stack though
20:12devncompojure and ring are ubiquitous
20:12justin_smiththat said, I did help develop a big old clojure framework, even comes with a built in cms where you can create new data models for the site, or add new data, in web forms
20:12devnyeah, there's room for both
20:12devnbut /historically/, the community has had an opinion on libraries instead of frameworks
20:13justin_smithdefinitely
20:13joobuswhat is everyone's opinion of datomic/ do most here stick to the SQLs with clojure?
20:13devnand like justin_smith: that said, ain't nothin wrong with a framework now and again
20:13devnjoobus: if you need datomic use it. if you dont know why you need it, figure that out first.
20:14justin_smithdevn: and how does one know they need datomic?
20:14devnby understanding what it is :)
20:14devncomparing it to relational DBs, document stores, k/v stores, etc.
20:15objectiveousIs there a simple way to inspect deftypes in order to understand what modifiers and annotations have been applied?
20:15bbloom,09
20:16clojurebot#<NumberFormatException java.lang.NumberFormatException: Invalid number: 09>
20:16bbloom,0644
20:16clojurebot420
20:16devn,08
20:16clojurebot#<NumberFormatException java.lang.NumberFormatException: Invalid number: 08>
20:16devn,07
20:16clojurebot7
20:16justin_smithobjectiveous: aren't annotations a javac thing? deftype does not use javac
20:16bbloomweeee leading zeros equal octal
20:16devnbbloom: haha, something i learned doing a project euler problem many moons ago
20:16devndid you just run into it?
20:17bbloomyeah, i was tuning a parameter, deleted a leading 1, and the results just seemed... wrong
20:17devn,(Integer/parseInt "09")
20:17clojurebot9
20:17devnbbloom: heh yeah
20:17TheMonarc"Never break their consumers. We agreed a standard early on to have a version number in resource paths (e.g. /1.x/products/12345/), such that if there is a need for a breaking change, a new version can be deployed side-by-side and get adopted by upstream consumers. Even though we still keep this capability, we haven’t needed to use it for years."
20:17justin_smithobjectiveous: that said, you can look at the interfaces some obejct implements
20:17TheMonarcfrom here: http://dev.mixrad.io/blog/2014/08/22/MixRadio-Architecture-Overview/
20:17justin_smith,(-> [] clojure.reflect/reflect :bases)
20:17clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.reflect, compiling:(NO_SOURCE_PATH:0:0)>
20:18justin_smith,(require 'clojure.reflect)
20:18clojurebotnil
20:18justin_smith,(-> [] clojure.reflect/reflect :bases)
20:18clojurebot#{clojure.lang.APersistentVector clojure.lang.IObj clojure.lang.IEditableCollection}
20:18devnclojure.reflect is so nice to have
20:18justin_smithindeed it is
20:18objectiveousjustin_smith, I'm not sure to what degree they are supported but I did see an email on the list describing the feature. Let me check...
20:19devn,(->> (clojure.reflect/reflect []) :members (map (comp str :name)) sort)
20:19clojurebot("EMPTY" "EMPTY_NODE" "NOEDIT" "_meta" "access$000" ...)
20:20justin_smithobjectiveous: annotations are not a thing that exists on the jvm - they are a concept in the javac compiler. Most Clojure code, and all deftypes, do not go through the javac compiler.
20:20devnobjectiveous: like extenders?
20:22objectiveousjustin_smith, this is what got headed down this train of thought. https://gist.github.com/richhickey/377213
20:22justin_smithobjectiveous: oh I may have to eat my words here
20:22justin_smithmy bad, sorry for the misinformation
20:23justin_smiththat gist shows how to get the annotations, which is exactly what you were asking
20:23objectiveousjustin_smith, ;-) But please don't stop helping me! I'm seriously in over my head. lol
20:23devnhttps://gist.github.com/richhickey/b5aefa622180681e1c81
20:24objectiveousjustin_smith, basically I'm trying to work with a clojure library that wraps the orientdb client java library.
20:25objectiveousIt does a load of javassit jazz and doesn't like my typedef as it's Final.
20:25llasramobjectiveous: Do you have a link to documentation about what you're trying to do with annotations?
20:26justin_smithobjectiveous: the class being final, or the fields on the object being final? I readily believe the latter, but that can be fixed with deftype
20:26objectiveousllasram, checking...
20:26justin_smithto the degree that making fields mutible is fixing anything
20:26devnheh, insane: https://github.com/ztellman/cambrian-collections/blob/master/generate/cambrian_collections/vector.clj
20:26devngenerate that java class with clojure!
20:27llasramobjectiveous: My experience is that many Java systems which use annotations at runtime via reflection need other things which you can't do with deftype, like have zero-argument constructors with annotations on the constructor
20:27objectiveousjustin_smith, I've already marked the fields so I believe the problem is with Class itself.
20:27devnyou could proxy, no?
20:29devnmaybe im missing the point
20:29devnbut there's also this: https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/genclass/examples.clj#L32
20:29objectiveousllasram, I suspect you're right and wonder what the most clojuresque approach would be?
20:30devnbah nevermind, i see what you mean now
20:31llasramobjectiveous: My experience is that Java is a pretty strong DSL for implementing Java classes
20:31bbloomllasram: heh.
20:32llasramobjectiveous: You can implement a tiny veneer Java class with exactly the interface (in the abstract sense), which then uses the Clojure Java API to load and run Clojure code for the actual implementation
20:33llasramobjectiveous: Here's a lightening talk rhickey gave describing the approach: https://skillsmatter.com/skillscasts/3864-impromptu-rich-hickey-lightning-talk
20:34objectiveousI think maybe I'm starting to see the light. I'm building up a rather large information model and orientdb allows me to interact with that model as Documents or Classes. I liked the idea of having types but maybe I should rethink this a little, if I want to live in clojure land.
20:34objectiveousllasram, cheers!
20:34devnhrm, llasram this looks like annotations on 0 argument constructors? https://github.com/pallet/clojure-maven
20:35llasramdevn: Where?
20:35devnugh, im tired or something. i think im leading you down the wrong path
20:35llasramobjectiveous: Good luck!
20:35devnsorry dude
20:36llasram~guards
20:36clojurebotSEIZE HIM!
20:36devnlol
20:37objectiveousThanks, folks. It's great to know there's a group of friendlies around to help a brother out, as they say.
20:50justin_smithobjectiveous: bonus, today I learned more about how annotations are actually implemented
20:57lavokadim geting file not exception when doing this
20:57lavokad (GET "/" [] (println (slurp "/resources/html/header.html"))))
20:57lavokad (GET "/" [] (println (slurp "/resources/html/header.html"))))
20:57lavokad (GET "/" [] (println (slurp "/resources/html/header.html"))))
20:57lavokad (GET "/" [] (println (slurp "/resources/html/header.html"))))
20:57lavokad (GET "/" [] (println (slurp "/resources/html/header.html"))))
20:57lavokad (GET "/" [] (println (slurp "/resources/html/header.html"))))
20:57lavokad (GET "/" [] (println (slurp "/resources/html/header.html"))))
20:58justin_smithlavokad: resources is on your path
20:58justin_smithand /resources probably does not exist
20:59justin_smithalso, if you want your code to work from an uberjar, change it to (slurp (io/resource "html/header.html"))
20:59lavokadim geting file not exception when doing this
20:59lavokadclear
20:59lavokadwtf
20:59lavokad?
20:59justin_smithlavokad: because /resources is not the same as resources
20:59lavokaddamn it..
20:59justin_smith(slurp "resources/html/header.html")
20:59justin_smithbut like I said, better to switch to io/resource and take out the resources/ part of the path, while you are at it
21:00lavokadsorry something broke and didnt see what i was writing
21:00lavokadjustin_smith: sorry, then in which dir am I when i do (GET "/" [] (println (slurp "/resources/html/header.html"))))
21:00lavokad?
21:01justin_smithlavokad: you are likely in your project dir
21:01justin_smithbut as I said multiple times, /resources/html/header.html is not the same as resources/html/header.html
21:01justin_smithyou want the latter
21:01justin_smiththe extra / means "look for this on the top level of my filesystem, ignoring my current directory"
21:03lavokadoh no
21:03lavokadi'm blind
21:03lavokad:D
21:04lavokadthank you!
21:30xeqianyone have a library for watching a file for changes?
21:31justin_smiththere are a few. You can also create a watcher object via interop with nio (jvm 7+)
21:31justin_smithhttps://github.com/ibdknox/watchtower this one looks straightforward
21:32justin_smithbut it uses polling, nio can use much more efficient OS level notifications (push from the system when the file is changed)
21:33justin_smiththis one uses the proper java 1.7+ watcher api https://github.com/derekchiang/Clojure-Watch
21:36justin_smiththere is also nio.file, we have a unit test on that lib which shows a lower level interop. https://github.com/ToBeReplaced/nio.file/blob/master/test/org/tobereplaced/nio/file_test.clj#L111
21:36xeqiyeah, I was glancing at Clojure-Watch but don't see a stop-watch
21:36xeqibut I can use it as a base
21:37justin_smiththe nio.file one is based on a watch-service object you create, which you can turn off, more or less
21:37justin_smithalso you can just cancel the thread that takes events from that watcher
21:38justin_smith(assuming you are doing the reasonable thing and putting watching in its own thread)
22:10TheMonarcanyone tried http://clojurekoans.com/ ?
22:14joobustrying it now :)
22:15amalloyTheMonarc: clojure koans is probably fine, but for a flavor of the same thing with less setup you could try 4clojure.com
22:24joobuskoans seems ok, solved a few just now
22:24joobusthen i got stuck
22:34mynomotoclojurescriptkoans.com are good too. I don't remember if there is anything clojurescript specific there.
22:37joobusdoes anyone here use vim-fireplace?
22:41mynomotoanyone?
22:41clojurebotanyone is anybody
22:42jgdavey_joobus: I do
22:44joobusi guess you would recommend it then?
22:44joobusi'm kind of a clojure noob at the moment
22:45jgdavey_If you're a vim user, definitely
22:45joobusi tried vim-fugitive (for git) but just use command line git instead
22:45joobusdidn't know if it was worth it
22:46jgdavey_I put together a screencast on using vim-fireplace a couple months back. It may be useful for the basics: https://vimeo.com/98052766
22:46mynomotojoobus: http://clojure-doc.org/articles/tutorials/vim_fireplace.html is a good place to start.
22:47joobusthank you
22:47joobusjgdavey_: i think i've run across your name in other searches as well
22:48joobuswere you at clojure west?
22:48jgdavey_I wasn't, unfortunately.
22:53joobushas anyone used lein fruit and lein droid? I'm wondering if it is possible to share common code between the two to deploy the same app to both platforms.
23:18danielcomptonI just got a Kinesis advantage, man it's brutal on my typing
23:18danielcomptonshowing up 10 years of shoddy muscle
23:18danielcompton memory from typing badly
23:20joobusdanielc: i looked at those but went with the microsoft natural whatver for $20
23:20joobusdo you like the keyboard?
23:21danielcomptonjoobus: still undecided. I think it needs a while to really give it a good test. It feels 'natural' on my hands which is good I guess.
23:22danielcomptonIt uses thumbs way more so now i have sore thumbs instead of sore pinkies
23:22joobuswhat did you use before?
23:23danielcomptonApple wireless keyboard
23:23danielcomptonI'm also keen to try technomancy 's
23:23danielcompton Atreus
23:23joobusi personally have a cast on my right hand at the moment so i use 1 hand and a "typing pencil" in my other. it sucks.
23:23danielcomptonadyn ergodox, and a keyboard.io
23:23joobusi hate the apple keyboards
23:24danielcomptonjoobus: that would be dumb. Are there one handed keyboard layouts?
23:24joobusno, the cast hopefully comes off in a week
23:25Jaoodjoobus: the microsoft natural is great :)
23:25joobusJaood: i agree, best bang for the buck
23:25maravillasthe ms natural 4000 feels like mush
23:26joobusmaravillas: are you a mechanical keyboard user? or what?
23:26maravillaskeys, that is
23:26Jaoodhttp://en.wikipedia.org/wiki/Microsoft_Natural_keyboard#mediaviewer/File:MS_Natural_Keyboard_Elite.png
23:26Jaoodhad that one but black
23:26maravillasi'm an ms natural 4000 user :)
23:26maravillasi haven't gotten around to replacing it
23:27taliosdanielcompton - keyboard.io looks nice
23:27danielcomptontalios: not out yet though :(
23:27maravillasi also use an apple magic keyboard and don't mind it
23:28Jaoodthe 4000 is bigger because of the media buttons
23:28taliosdanielcompton - *sadface*
23:28danielcomptonmaravillas: I liked the apple keyboard until i started using emacs
23:28joobusi have bigger hands, the 4000 lets me stretch my hands out a little better. the apple keyboards are too cramped for me.
23:28maravillasit is a little awkward, but thankfully i've never had rsi issues with it, somehow
23:30danielcomptonmy favourite is still https://farm3.staticflickr.com/2787/4397554484_739ae62eee_b.jpg
23:30danielcomptonfrom technomancy
23:30joobusdanc, lol
23:30joobusdid you use one of those?
23:31taliosdanielcompton - combine that with http://www.muldersworld.com/photo.asp?id=25864 and you're a winner
23:31taliosor just a sad loser :)
23:31danielcomptoncomputering anywhere. Just add an Oculus Rift
23:39joobusdoes anyone here use the nginx-clojure module with nginx?
23:39justin_smithjoobus: it's silly
23:39justin_smithjust use nginx as a reverse proxy
23:39joobusto a ring server?
23:39justin_smithright
23:40justin_smithhttp-kit is a good choice
23:40justin_smithit can be helpful to run varnish too
23:41joobusnginx-clojure claims to be the fastest https://github.com/ptaoussanis/clojure-web-server-benchmarks
23:42joobusso i was curious how well it works
23:42joobusbut the install tutorial was written in broken english and i kinda got lost
23:42amalloyjoobus: i would not advise using nginx-clojure