#clojure logs

2015-06-12

01:20ronh_-scon 'a disconnect
01:25mercwithamouthso...has anyone written a syntax highlighter before?
01:26mercwithamouthi've always loved crayon syntax highlighter but it's written in php and jquery... i'm really tempted to try writing one that works as well in clojurescript
01:28mercwithamouththough it seems like a daunting project at my level
03:36kapcompared to PersistentVector is there a performance difference when getting indexed items from PersistentList ?
03:36kapaka, is it worth modifying conj like so? (conj (or (k m) []) v)
03:37hiredman,(doc fnil)
03:37clojurebot"([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched."
03:38TEttinger(inc hiredman)
03:38lazybot⇒ 80
03:41kap,(class (conj nil 3))
03:41clojurebotclojure.lang.PersistentList
03:41kap,(class (conj (or nil []) 3))
03:41clojurebotclojure.lang.PersistentVector
04:51WickedShelljustin_smith, thats the impression I had, but hadn't been able to find any documentation on it either way (and was far from a computer on which to test from)
05:57whodidthiswhats a command in clojure-mode/paredit to move forms backwards/forwards in a list
06:07elvis4526hey guys whats the best way to delete a nested key in a map ?
06:09oddcully,(update-in {:a {:b {:c 1 :d 2}}} [:a :b] dissoc :d)
06:09clojurebot{:a {:b {:c 1}}}
06:10elvis4526that's really neat - thanks
07:40acron^is there a form to describe 'if x is a var, perform fn on it, else if x is a sequence of vars, perform fn on each one'?
07:40acron^without a load of (if (seq? etc..
07:41justin_smithacron^: is (range) a sequence of vars?
07:41justin_smith(I mean literally it is not, just making sure I understand what you mean)
07:41Empperi,(doc var?)
07:41clojurebot"([v]); Returns true if v is of type clojure.lang.Var"
07:41justin_smithEmpperi: I don't think acron^ means var at all
07:41Empperi,(doc sequence?)
07:41clojurebotIt's greek to me.
07:41acron^maybe i dont mean var
07:42Empperi,(doc sequential?)
07:42clojurebot"([coll]); Returns true if coll implements Sequential"
07:42acron^for this example, interchange var with string
07:42justin_smithOK, you mean value
07:42acron^sorry :) yes
07:42justin_smithacron^: the snarky reply to your situation is "fix the code that can't decide whether to return a collection or not"
07:43acron^hmmm
07:43justin_smithacron^: for example, in my code I often use collections of collections - how would any function know if the collection I provided was one collection out of a sequence of them, or my top level collection?
07:44justin_smithacron^: if I am using an API that returns sometimes a collection, sometimes a string, I like to make a thin wrapper that puts the string into a vector, just so all my other code doesn't have to worry about it
07:44acron^my instruction is "make this fn accept a value or a seq of values" so my immediate reach is (if (seq? x) etc...
07:45justin_smithacron^: the reason I avoid ever having that kind of logic is that it is contagious
07:45acron^so yeah, i could just throw an (if (seq? x) x [x]) in place
07:45justin_smithyou allow one function to work that way, and suddenly every other function that uses it needs a similar if check...
07:45justin_smithacron^: yes, that is the sane way to do it :)
07:45acron^thanks justin_smith :)
09:15CookedGryphonhas anyone here used bolth?
09:16CookedGryphonit looks pretty good, but I want to use it on my CI server and it doesn't seem to have a command line way of just doing run all tests?!
09:16CookedGryphoneven if I make a main method that calls run-all-tests, I need to explicitly import all my test namespaces, it doesn't pick up everything from the classpath
09:54ionthas_(doc foreach)
09:54clojurebotI don't understand.
09:55ionthas_Is there any function to apply a function to each element of a vector?
09:55code-ape ionthas_: I'm not super experienced with clojure yet, but won't map work?
09:59oddcully,(map #(* % %) [1 2 3])
09:59clojurebot(1 4 9)
10:01joegallo,(mapv #(* % %) [1 2 3]) ; if it's important to you that you get a vector back rather than a sequence
10:01clojurebot[1 4 9]
10:09rumblepackHi everyone :D
10:10ionthas_thanks! I forgot mapv :)
10:10ionthas_(just doing my first project in clojure)
10:10rumblepackCool! How is it going?
10:11joegallooh, in that case, here: ((()((())))(())) i've got some extra parens you can have
10:11oddcullyyou never stated the returntype you are after ;p
10:11joegallo:)
10:12code-apeAlso, just out of curiosity, has anyone started using the clojure.core/typed package?
10:12rumblepackNever needed to so far.
10:13shemcode-ape: i have tried to but it's pretty painful if you have lots of dependencies
10:15code-apeshem: yeah, I was trying it with aleph and that was my experience.
10:15ToxicFrogYeah, I've tried using it a few times, but it chokes on dependencies, it has trouble with command line args, eventually I just gave up.
10:15ToxicFrogProbably going to give it another shot next year and see if it's mature enough to use then.
10:15ToxicFrogI really like it as a concept, the implementation just isn't there yet.
10:16code-apeToxicFrog: I really like the idea of it too, I've debated taking some time to type declare some of the smaller libraries I use and throw our a PR for it.
10:17ToxicFrog(I also managed to crash it outright a few times in totally unhelpful ways, which ate up a lot of my patience for dealing with it)
10:54ionthas_I have a vector of vectors [[1 2] [3 4] [5 6]] and I want to apply a function to calculate the product of all the sub-vectors #(apply * %). The problem I have is, if I apply (mapv %(apply * %) [[1 2] [3 4] [5 6]]) I get the only the result of that operations [2 12 30]. What I really want is: [[[2 [1 2]] [12 [3 4]] [30 [5 6]]]. I implemented that with a loop/recur but I would like to find a more idiomatic way.
10:55justin_smith,(mapv (juxt (partial apply *) identity) [[1 2] [3 4] [5 6]])
10:55clojurebot[[2 [1 2]] [12 [3 4]] [30 [5 6]]]
10:56justin_smithsomething like that?
10:56ionthas_wow thanks justin_smit. Exactly like that.
10:56justin_smith(inc juxt)
10:56lazybot⇒ 22
10:56ionthas_I didn't know the functions juxt and partial
10:57justin_smithionthas_: check out http://conj.io - just looking around on that page every time you want to figure out a new problem helps learning the core language
10:57justin_smithmost of clojure.core is on that page
10:58ionthas_thanks :)
10:58lasergoat If I want to use core.async's poll! and offer!, what's my best option? There hasn't been a release in a while
11:01lasergoati'm happy to use snapshots or whatever
11:02jgdaveyHow would I compare two sequences, given a fn f for comparing, that would return something like [[in-a in-b] [nil only-in-b] [only-in-a nil]] ?
11:02justin_smithjgdavey: clojure.data/diff
11:03justin_smith,(require 'clojure.data)
11:03clojurebotnil
11:03jgdaveyDoes data.diff allow custom fn for compare?
11:03justin_smith,(clojure.data/diff {:a 0 :b 1 :c [1 2 3]} {:a 1 :b 1 :c [1 2 3 4]})
11:03clojurebot({:a 0} {:c [nil nil nil 4], :a 1} {:c [1 2 3], :b 1})
11:03justin_smithhmm
11:09jgdaveySimiliar in concept to a full outer join
11:13andyf_jgdavey: Easiest way might be modifying source code of clojure.data/diff
13:25expezwhen I don't want to use (concat a b c) because that would blow the stack with LazySeq nonsense, what should I do instead? I re-wrote it using ->> and into but that looks a lot clunkier.
13:42devnexpez: could you give a more concrete example of what you're trying to achieve?
13:42expezdevn: https://github.com/clojure-emacs/refactor-nrepl/commit/cdc4c8dbcc7b61c3809321f738597266657b9b73
13:43expezI didn't expect this at all because the numbers involved are so small, but I just had my stack blown :p
13:44justin_smithexpez: an alternative would be a reduce with conj, but that's effectively what into is anyway
13:45justin_smithexpez: perhaps a reduce of into though
13:45justin_smith,(reduce into [] '((1 2 3) (a b c)))
13:45clojurebot[1 2 3 a b ...]
13:45justin_smithexpez: that should clean up your thing a big?
13:45justin_smith*bit
13:46expezyeah, that is prettier :)
13:46justin_smith(reduce into (when-let ...) [(slamhound/cantidates ...) (slamhound/cantidates ...))
13:47devnexpez: http://stuartsierra.com/2015/04/26/clojure-donts-concat
13:47expezdevn: that blogpost is actually why I instantly knew what the problem was when I saw the stacktrace :)
13:51devn:D
13:53llzI'm an experienced Haskeller. I'll be reading Clojure at a new job. I've read some basic info on Clojure. Any pointers for further reading?
13:54justin_smithllz: if you already have some fp background, joy of clojure is good
13:54justin_smithllz: also, stuartsierra's blog is a good source for good clojure style and coding guidelines
13:55TEttingerllz: comp is going to be familiar. right to left function composition like the dot in haskell
13:56TEttingerit isn't used super often, but can be very concise. there are other fns in clojure that draw from haskell like that
13:56TEttinger(doc juxt)
13:56clojurebot"([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"
13:56TEttingerjuxt is joy
13:56llz(doc comp)
13:56clojurebot"([] [f] [f g] [f g & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."
13:57TEttingerother fun functions: reductions is scan or scanl or something. reduce is foldl.
13:58TEttinger,(reduce *' (range 2 10))
13:58clojurebot362880
13:58llzHow does ->> relate to comp? Basically just flipped?
13:58TEttingercomp returns a new fn
13:58TEttinger->> returns the result
13:58llzAh
13:58TEttinger,(reductions *' (range 2 10))
13:58clojurebot(2 6 24 120 720 ...)
13:59TEttinger,(->> [1 2 3] (map inc) (reduce +))
13:59clojurebot9
13:59TEttingerwhich is the same as
14:00TEttinger,(reduce + (map inc [1 2 3]))
14:00clojurebot9
14:00TEttingerbut the "threading macros" -> and ->> are very handy when you want to clarify that something is being passed consecutively
14:01TEttingerthere's also doto when dealing with mutable (typically from java) objects
14:01TEttinger,(doto (new java.util.Random) .nextInt)
14:01clojurebot#object[java.util.Random 0x1879219e "java.util.Random@1879219e"]
14:02llzIs partial application a common idiom?
14:02TEttingerdoto returns the actual object that is being mutated, what's a better example for that...
14:02TEttingernot often. there is ##(doc partial)
14:02lazybot⇒ "([f] [f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."
14:03TEttingerpartial can be more clear, especially with variadic fns, but if you want a certain number of args the anonymous fn syntax is probably more common
14:04TEttinger,(reduce #(/ %2 %1) [1 2 3 4 5])
14:04clojurebot15/8
14:04Cr8,(doto (java.util.ArrayList.) (.add 1) (.add 2))
14:04clojurebot[1 2]
14:04TEttingerah, good example Cr8
14:04TEttinger(inc Cr8)
14:04lazybot⇒ 4
14:05TEttinger(closing dot is the same as calling new on the preceding class, closing dot is preferred)
14:05Cr8doto is mostly handy in interop situations -- i think it is or at least used to be listed under interop in the docs
14:05TEttingersounds about right
14:06TEttingerit is similar to the threading macros though
14:06llz(The preceding comma you all've been including is just for clojurebot, right?)
14:06Cr8yeah fun thing you can do with it is toss a (doto println) in the middle of a -> -- doesn't affect the subject but prints it out in the middle of your -> chain
14:06Cr8yes
14:07Cr8commas are whitespace in clojure
14:07justin_smith,,,,,,,,,,,,,,,,,,42,,,,,,,,,,,,,
14:07clojurebot42
14:09Cr8,(-> 1 inc (doto prn) inc)
14:09clojurebot2\n3
14:10llzThanks all
14:48dnolenBronsa: ping
14:58Bronsadnolen: pong
14:59TEttingerstomach: pang
15:09noncomsome long time ago someone, maybe even technomancy has dropped here a link to a fun video about maven, a parody on some known poetry "this just raven" where it was about "this just maven".. does anyone remember where to find it?
15:11Xorlevhttp://timberglund.com/blog/2012/08/03/the-maven/ ?
15:15noncomXorlev: truly it is! :)
15:15noncomthank you very much
15:24noncomhow do i file-seq but only 1 level?
15:24noncomi do not want recursive...
15:24dnolenBronsa: so I think I understand what needs to happen w/o messing around with full namespace reification.
15:25Empperinoncom: (-> (File. "/foo/bar") (.listFiles))
15:25noncomah!
15:25dnolenBronsa: basically we need to read the ns form to compute the alias map as well as information for ns-map
15:25Empperijust use the java api
15:25noncomthanks!
15:25Empperireturns a java array of File objects
15:25Empperiif you want that to a seq, then just convert into one
15:25Empperiand np
15:26dnolenthen we can bind *ns* to an synthetic ns thing that more or less simulates namespaces in Clojure. I think this is enough for tools.reader
15:26justin_smithnoncom: ##(into [] (.list (java.io.File. ".")))
15:26lazybotjava.security.AccessControlException: access denied ("java.io.FilePermission" "." "read")
15:26justin_smithnoncom: anyway, that will work on your machine
15:27noncomyeah!
15:27justin_smithoh, on scrollup I see listFiles above - but .list lists directories too
15:28timvishershould criterium output it's bench results when executed from an uberjar?
15:29timvisheror do you need to do something special to get that to work?
15:29timvisheras far as i can tell it uses println so it should just print?
15:30Bronsadnolen: are you saying that tools.reader should parse the ns form?
15:31dnolenBronsa: nah, I think we can sort it out over in ClojureScript so the ns and resolution stuff just ports over
15:32dnolenin tools.reader
15:33timvisherhere's an example. https://gist.github.com/timvisher/8e9da8d92fee8cdba482
15:34timvishernotice how i get the evaluation count and such but none of the other stats
15:40timvisheri just added example repl output for the same call to https://gist.github.com/timvisher/8e9da8d92fee8cdba482
15:46timvisherbizarre. if i wrap the call to bench in `with-out-str` and then println on it works...
15:48tiger`my emacs/cider M-. doesn't jump to symbol anymore. Does it work for you in latest cider ?
15:48timvishertiger`: define latest cider
15:48tiger`cider from melpa
15:48timvishertiger`: melpa what? what's the cider version report?
15:49tiger`0.9.0-snapshot
15:50tiger`"CIDER 0.9.0snapshot (package: 20150612.315)"
15:50timvishertiger`: you have that in your dependencies as well? in `.lein/profiles.clj` or elsewhere?
15:50timvishermmm. fwiw it works for me in melp stable on 0.8
15:50timvisherbut that sounds like you have the basics right
15:50tiger`yes, [cider/cider-nrepl "0.9.0-SNAPSHOT"]
15:52tiger`it goes to emacs prompt Symbol:
15:52tiger`and prints "no source location" :-(
15:59jonathanjdo the bindings in (with-open) have to be closeable or can i use it as a general purpose let?
16:00amalloyjonathanj: try it and see
16:01amalloyeg, (with-open [x 5] (inc x))
16:02jonathanjcute :)
16:21irctchey I'm having difficult understanding symbols vs keywords
16:21irctcI know a keyword would be used in a map, because it strictly evaluates to itself
16:21irctcand a keyword can be a symbol
16:21irctcim just trying to get a more concrete idea in my head
16:22justin_smithirctc: keywords cannot be symbols
16:23irctcbut what about ':foo?
16:23justin_smith,(type ':foo)
16:23clojurebotclojure.lang.Keyword
16:23justin_smiththat's not a symbol
16:23justin_smith' is not the "create a symbol" operator
16:23irctc(symbol)
16:24justin_smith,(type (symbol :foo))
16:24clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to java.lang.String"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.lang.String"\n :at [clojure.core$symbol invoke "core.clj" 550]}]\n :trace\n [[clojure.core$symbol invoke "core.clj" 550]\n [sandbox$eval49 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792...
16:25arohner_irctc: keywords evaluate to themselves, symbols evaluate to something else
16:25justin_smith,(def foo 'bar)
16:25clojurebot#'sandbox/foo
16:25justin_smith,(def bar 'foo)
16:25clojurebot#'sandbox/bar
16:25justin_smith,(iterate eval 'foo)
16:25clojurebot(foo bar foo bar foo ...)
16:26justin_smithwith more room to print you could even make a nice circular chain
16:28irctcthanks arohner
16:28irctcand justin
16:28justin_smithhttps://www.refheap.com/102484 <- a nice cycle
16:28kaiyin_this might be a bit off-topic, but how does the following bit magic work? 0x00 << 24 | b & 0xff
16:29justin_smith,(bit-shift-left 0 24)
16:29clojurebot0
16:29kaiyin_it's supposed to convert a byte into an "unsigned int"
16:29amalloy0 << 24? that is bizarre
16:29justin_smithinorite
16:30amalloyi guess the compiler will optimize it out, and then it serves as a hint to the human reader or something? or maybe it is just a special case of a more general "mask off some 8 bits" algorithm that looks dumb in this case
16:30amalloykaiyin_: it is the same as just: b & 0xff
16:31kaiyinok, i see.
16:45jonathanjusing (for) is it possible to determine whether i'm iterating the last element?
16:45amalloyjonathanj: no, but you probably don't have to
16:45justin_smithjonathanj: nope
16:45jonathanji want to treat the last element differently to any other, any suggestions?
16:46amalloyjonathanj: my argument is that you probably done need to do that. why do you think you do?
16:46amalloy*don't
16:47jonathanji'm rendering a tree, every other element should turn out like "|-- key: value" while the last element should turn out like "`-- key: value"
16:50amalloy,(let [nodes (range 6), decorators (-> (map (fn [a b] a) (repeat "|--") (rest nodes)) (concat ["`--]))] (map str nodes decorators)) maybe?
16:50clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading string>
16:50TimMcTHat's a pretty good reason.
16:50amalloy,(let [nodes (range 6), decorators (-> (map (fn [a b] a) (repeat "|--") (rest nodes)) (concat ["`--"]))] (map str nodes decorators))
16:50clojurebot("0|--" "1|--" "2|--" "3|--" "4|--" ...)
16:50amalloy&(let [nodes (range 6), decorators (-> (map (fn [a b] a) (repeat "|--") (rest nodes)) (concat ["`--"]))] (map str decorators nodes))
16:50lazybot⇒ ("|--0" "|--1" "|--2" "|--3" "|--4" "`--5")
16:50amalloyit's a bit ham-handed, probably there is a nicer solution
16:51TimMcOooh, I always forget about using rest to count to one from the end.
16:52jonathanjugh, i sometimes find myself with a nested vector and i don't know why
16:52justin_smithjonathanj: that sounds like join
16:53amalloythat was my reaction too, justin_smith, but i think jonathanj's use case is distinct enough that join doesn't really help
16:53justin_smithahh, OK
16:55jonathanjhow do i write the equivalent of Python's zip() in Clojure?
16:55jonathanjzip([1, 2], [3, 4]) -> [[1, 3], [2, 4]]
16:55justin_smith,(map list [:a :b :c] [1 2 3])
16:55clojurebot((:a 1) (:b 2) (:c 3))
16:56justin_smith,(mapv vector [:a :b :c] [1 2 3])
16:56clojurebot[[:a 1] [:b 2] [:c 3]]
16:56Bronsa,(zipmap [:a :b :c] [1 2 3])
16:56clojurebot{:a 1, :b 2, :c 3}
16:56justin_smith,(mapv vector [:a :b :c] [1 2 3] ["a" "b" "c"])
16:56clojurebot[[:a 1 "a"] [:b 2 "b"] [:c 3 "c"]]
17:08jonathanjdoes (map f xs ys) end when the longest or shortest seq ends?
17:09jonathanjshortest, it looks like
17:09justin_smithyes, shortest
17:10jonathanjcan i iterate backwards with (for)?
17:11justin_smith(for [x (reverse y)] ...)
17:11justin_smiththat's the closest you can get I think
17:11jonathanj,(reverse (map list (reverse [:a :b]) (cons "`" (repeat "|"))))
17:11clojurebot((:a "|") (:b "`"))
17:12jonathanjnot sure if reverse is terrible in terms of efficiency (like it is in Python)
17:12justin_smithjonathanj: also, regarding the "detect the last item" thing, butlast might help (and just manually stick the last tihng on the end)
17:13jonathanjhow do i actually stick the last thing on?
17:13justin_smithjonathanj: a cheap version of reverse if you are also building a collection is (into () ...) or to conj onto () at each step
17:13justin_smith,(into () (range 10))
17:13clojurebot(9 8 7 6 5 ...)
17:14justin_smiththere's not point if all you are doing is reversing, but if you are doing other stuff too it can make sense
17:14jonathanjhrm
17:14jonathanji'm sorting
17:14justin_smith,(reduce (fn [c x] (conj c (inc x))) () (range 10))
17:14clojurebot(10 9 8 7 6 ...)
17:14jonathanjmaybe i can sort in reverse?
17:14justin_smithyeah, you can use a reversed comparitor
17:15jonathanj(sort-by < coll)?
17:15justin_smith,(sort-by < (range 1000))
17:15clojurebot(0 1 2 3 4 ...)
17:15justin_smith,(sort-by > (range 1000))
17:15clojurebot(0 1 2 3 4 ...)
17:15justin_smith,(sort > (range 1000))
17:15clojurebot(999 998 997 996 995 ...)
17:16jonathanjmy coll is a map
17:16jonathanj,(sort < {:a 1 :b 2})
17:16clojurebot#error {\n :cause "clojure.lang.MapEntry cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.MapEntry cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers lt "Numbers.java" 221]}]\n :trace\n [[clojure.lang.Numbers lt "Numbers.java" 221]\n [clojure.core$_LT_ invoke "core.clj" 870]\n [clojure.lang.AFunction compare "AFunction.ja...
17:16justin_smith,(sort-by key > {1 0 2 -1 3 -2})
17:16clojurebot([3 -2] [2 -1] [1 0])
17:17jonathanj,(sort-by < {:a 1 :b 2})
17:17clojurebot([:a 1] [:b 2])
17:17justin_smithbonus points, getting to show what sort-by is actually for
17:17jonathanjhrm, that sorts in the opposite direction on my machine
17:18jonathanj=> (sort-by < {:a 1 :b 2})
17:18jonathanj([:b 2] [:a 1])
17:18justin_smithjonathanj: look at my sort-by again
17:20jonathanjokay, but that doesn't actually work for a map of my shape
17:20dagda1How could I display this as a number and keep the trailing 0's "0.500000"
17:20jonathanj,(sort-by key > {:a 1 :b 2})
17:20clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers gt "Numbers.java" 229]}]\n :trace\n [[clojure.lang.Numbers gt "Numbers.java" 229]\n [clojure.core$_GT_ invoke "core.clj" 1040]\n [clojure.lang.AFunction compare "AFunction.jav...
17:20jonathanji just want to order the keys alphabetically
17:20justin_smith,(sort-by identity (comp (partial * -1) compare) {:a 0 :b 1 :c 2})
17:20clojurebot([:c 2] [:b 1] [:a 0])
17:20justin_smithdagda1: format
17:21justin_smith,(sort-by key (comp (partial * -1) compare) {:a 0 :b 1 :c 2}) ; if you really only care about the key
17:21clojurebot([:c 2] [:b 1] [:a 0])
17:21justin_smithjonathanj: ^
17:21jonathanjwhat the heck is the *-1 for
17:21jonathanjinvert the compare result?
17:22justin_smithjonathanj: exactly, a comparator returns a number
17:22justin_smithto reverse sorting, you can flip the sign of hte number
17:22dagda1justin_smith will that not format as a string
17:22amalloyjustin_smith: (= (partial * -1) -)
17:22jonathanjthat seems crazy unexpressive
17:22justin_smithamalloy: ! I always forget
17:22jonathanjeven so
17:22justin_smith,(sort-by key (comp - compare) {:a 0 :b 1 :c 2}) ; thanks amalloy
17:23clojurebot([:c 2] [:b 1] [:a 0])
17:23jonathanj,(sort-by key (comp - compare) {:a 1 :b 0 :c 2})
17:23clojurebot([:c 2] [:b 0] [:a 1])
17:23justin_smith(inc amalloy)
17:23lazybot⇒ 279
17:23jonathanj(inc amalloy)
17:23lazybot⇒ 280
17:23jonathanj(inc justin_smith)
17:23lazybot⇒ 263
17:23amalloyjonathanj: make sure you're not just using "unexpressive" to mean "different from how python does it"
17:24jonathanjamalloy: no i mean that "negate a number to change the sorting direction" is kind of a weird way of saying "sort this thing the other direction"
17:24jonathanjin python, for example, sorted(..., reverse=True) does what you'd expect
17:25amalloyit's more flexible, though. imagine if every function like sort had 4 different flags for all the ways you'd want to sort things
17:25amalloyjust allowing a single function argument allows all that power, and more, without adding a bunch of special cases
17:25justin_smithright, I could make my own silly comparator
17:25amalloylike i bet python's sort allows you to pass a function too, which means that all those flags are just for convenience
17:25jonathanjwell if < or > were comparators that would be useful
17:26justin_smith,(sort-by key (comp count str) {:longest 0 :longer 1 :long 2})
17:26clojurebot([:longest 0] [:longer 1] [:long 2])
17:26amalloy,(comparator >)
17:26clojurebot#object[clojure.core$comparator$fn__4659 0x2a851004 "clojure.core$comparator$fn__4659@2a851004"]
17:26amalloy~def comparator
17:27amalloynow > is a comparator
17:27justin_smithoh yeah, that str comparator is totally wrong
17:27jonathanjokay, but:
17:28TimMcjonathanj: (def reverse-comparator (partial comp -)) :-P
17:28jonathanj,(sort-by key (comparator <) {:a 1 :b 0 :c 2})
17:28clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers lt "Numbers.java" 221]}]\n :trace\n [[clojure.lang.Numbers lt "Numbers.java" 221]\n [clojure.core$_LT_ invoke "core.clj" 870]\n [clojure.core$comparator$fn__4659 invoke "core....
17:28TimMcNow it's expressive.
17:28amalloywell yes. < and > work only on numbers. which is kinda lame, but that's the price you pay for host-level performance
17:28justin_smithjonathanj: well, < doesn't work on keywords, compare does
17:30justin_smithTimMc: or (def revcomp (comp - compare)) to specialize for reverse sorting
17:30justin_smith,(sort-by identity (comparator rand) (range 10))
17:30clojurebot#error {\n :cause "Wrong number of args (2) passed to: core/rand"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/rand"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [clojure.core$comparator$fn__4659 invoke "core.clj" 2967]\n [clojure....
17:30justin_smithheh
17:32justin_smith,(sort (fn [_ _] (- (rand-int 2) 1)) (range 10))
17:32clojurebot(2 3 5 7 6 ...)
17:33andyf_justin_smith: Trying to write shuffle the hard way?
17:34amalloyi can never quite keep straight exactly why that is a bad shuffle implementation
17:34amalloyit's biased in some weird way
17:34justin_smithandyf_: just goofing around
17:35justin_smithhttps://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for anyone else curious
17:36andyf_I love that dance.
17:36justin_smithhaha
17:37jonathanj#clojure is always so educational, i have a hundred new ways to think about things now
17:37jonathanj<3
17:39justin_smithoh wow - fisher-yates shuffle can be done lazily
17:40justin_smithI mean, the clojure shuffle just calls the java method, but we could totally have a lazy shuffle if we wanted it
17:40justin_smiththe input would still have to be fully realized, but the output could be lazy
17:41andyf_justin_smith: Meaning it maintains state of all of the remaining elements that haven't been output yet, and each 'pull' randomly selects one of them uniformly and updates the internal state? Makes sense.
17:41justin_smithamalloy: that page mentions why my silly random sort is a bad shuffle - it's dependent on the sorting algo how bad it is
17:41justin_smithandyf_: exactly
17:42justin_smithandyf_: so the selection of new results can be lazy
17:42jonathanjif i wanted a way to whilelist keys from a map (for display purposes) a set seems reasonable, but assuming i have an arity that takes the whitelist and an arity that does not take a whilelist (assuming no whitelist means "everything") how do i actually element this in a concise way?
17:42jonathanji guess what i want is some magical "everything" set
17:42amalloyjustin_smith: there's a lazy shuffle in useful
17:42justin_smithamalloy: oh, cool
17:43andyf_jonathanj: Set theorists go mad contemplating everything sets, I think.
17:43amalloythere are some people who say it's not actually fisher-yates, because an important property of fisher-yates is that it's done in-place
17:43justin_smithjonathanj: well, a handy thing is that sets act as functions, returning the result of a lookup
17:43jonathanjactually, i guess if testing the whitelist is implemented as a function (#{...} k) then for the everything case i can pass (fn [_] true)
17:43justin_smith,(#{:a :b :c} :a)
17:43amalloybut i don't really agree, just like quicksort/mergesort can be done functionally but not in place
17:43jonathanjor well identity
17:43andyf_Practically, you can have code like (or show-all (in-show-set k)) before deciding whether to show a key.
17:43clojurebot:a
17:43zimablue{set of all things not contained in this set}
17:43justin_smithjonathanj: which means that you could take a predicate, which could be a set, or (constantly true)
17:44justin_smithsince all things not nil or false count as true for clojure tests
17:44TimMcjonathanj: Do you know that you'll never have nil or false as a value?
17:44jonathanjTimMc: no
17:44jonathanjwell actually, nil or false will never be keys
17:44jonathanjso i guess that's a yes
17:45justin_smithjonathanj: so yeah, (fn [_] true) or (constantly true) or however you want to express it can take the place of the universal set
17:45justin_smithfor this specific case that is
17:47jonathanji can never remember what (constantly) is called
17:47amalloy(complement #{})
17:47justin_smith(repeatedly (forget constantly))
17:47amalloya sillier way of doing it
17:48TimMc&(map (complement #{}) [nil false true :cats])
17:48lazybot⇒ (true true true true)
17:49TimMcOh wait, that wasn't what I meant to write.
17:50TimMcNever mind. I was thinking for a sec that sets could take an optional not-found arg, but they don't.
17:50amalloyreally?
17:50amalloy,(#{} 1 2)
17:50clojurebot#error {\n :cause "Wrong number of args (2) passed to: PersistentHashSet"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: PersistentHashSet"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [sandbox$eval49 invoke "NO_SOURCE_FILE" 0]\n [clojure...
17:50amalloywell that's lame
17:50justin_smiththat's oddly inconsistent!
17:51amalloyjustin_smith: clojure is inconsistently odd, so it fits
17:52stain,(:blah {} :notfound)
17:52clojurebot:notfound
17:53andyf_Vote early, vote often: http://dev.clojure.org/jira/browse/CLJ-1305
17:53justin_smith(inc amalloy)
17:53lazybot⇒ 281
18:16zimablue`test
18:16TEttingerhello
18:21stainhi!
18:25musicm122Ello all
18:26musicm122Is this the best place to ask noobish questions?
18:26musicm122nm going to clojure-beginner
18:28andyf_musicm122: You may ask noobish questions here, too, if you wish.
18:35musicm122Cool
18:35musicm122thanks @andy_f
18:36musicm122well I've been trying to write a function with multi arity
18:36musicm122that returns a file's extension
18:36musicm122https://gist.github.com/musicm122/6d2eb4fd5dd5d538cfaf
18:38musicm122but as it says in the comments I've been getting invalid # of args
18:40musicm122the single arg version works fine (defn getFileExt [arg] (str (subs arg (.lastIndexOf arg "." ))))
18:42musicm122but when I try to use the multi parity version
18:42musicm122(defn getFileExt [arg] (str (subs arg (.lastIndexOf arg "." ))) [& *args*] (apply getFileExt *args* ))
18:42amalloymusicm122: that is not how multiarity works
18:42amalloyremember that (defn foo [x] y z q) evaluates y, then z, then q
18:42amalloyhere [& args] is z, and evaluating that makes no sense
18:42musicm122k
18:42amalloyyou need extra parens to group the various arities
18:43amalloy(defn foo ([x] a) ([y z] b))
18:45musicm122k testing
18:51musicm122I should still be able to recur my version with & to the one that takes a single arg right?
18:51musicm122such that
18:51musicm122(defn getFileExt ([arg] (str (subs arg (.lastIndexOf arg "." )))) ([& *args*] (apply getFileExt *args* )) )
18:53amalloyno
18:53amalloyoh you can do that, sure. you just can't use recur
18:53amalloybut also that is a broken implementation of your &args arity anyway. it will never do anything good
18:54musicm122AH
18:54musicm122 (defn getFileExt ([arg] (str (subs arg (.lastIndexOf arg "." )))) ([arg & *args*] (apply getFileExt arg *args* )) )
18:54musicm122I have to actually supply a 1st before I can supply the rest
18:54amalloythat is still never going to do anything good
18:54amalloythe multi-arity case will jsut call itself endlessly
18:55musicm122gah
18:55amalloyyou have to simplify the problem somehow before recurring, otherwise the recursion never terminates
18:55amalloyit's like (defn + [x y] (+ x y))
18:55amalloytrue, but not very useful
19:00pkilleanI am trying the eduction example from http://clojure.org/transducers in a repl, getting TypeError: coll.cljs$core$IReduce$_reduce$arity$2 is not a function. Is this a bug?
19:00pkillean^(cljs)
19:04pkillean^nvm got it
20:52zhadnI'm defining a list coolList (def coolList '(1 2 3 4 5)), but when I try and peek/pop with (peek coolList) I get "Unbound can not be cast to persistentstack". But when I (peek '(1 2 3 4 5)) that works fine?
20:52zhadnI can't figure out why
20:55amalloyzhadn: you evidently are not defining that list
20:55amalloyeg, if you try to evaluate just coolList itself, you will be told it is unbound
20:55zhadnim working in TryClojure
20:56zhadnand evaluating coolList will return the value
20:56zhadnbut when I try and operate on it, it throws that exception
20:56zhadnso Im just setting it in a REPL
20:56amalloytry using a real repl. tryclojure probably has some weird eviction policy for vars
20:57zhadnyep you're right
20:57zhadnworks fine with lein
20:57zhadnthanks!
21:57jeramy_sgood evening all
21:58jeramy_sI am completely new to Clojure, actually I haven't even started yet. Was wondering what the best resources are for learning Clojure
22:02andyfjeramy_s: The clojure.org getting started page has several links to on-line resources created by others: http://clojure.org/getting_started in the Community section
22:02andyfI haven't used them myself, but some people seem to like "Clojure for the Brave and True" and "Clojure from the ground up"
22:03andyfOnly reason I haven't read them is that they were written after I was already quite familiar with Clojure.
22:03jeramy_sHas anyone read the prag prog book, Programming Clojure?
22:03jeramy_sI meant to ask if you've heard good things about the book
22:06whompis there a value-map function which, given a hash map, returns one with the values mapped?
22:07andyfI read 1st ed. long ago. I guess there is a 2nd now? I haven't read through all of the "Clojure Programming" book published by O'Reilly, but from the parts that I have, and my recollections of the "Programming Clojure" book, my preference is for the O'Reilly one.
22:07justin_smithwhomp: it's very easy to write, but it doesn't exist in the core language
22:07whompjustin_smith, ty :)
22:08justin_smith#(into {} (for [[k v] %2] [k (f %1)]))
22:08justin_smitherr, not quite
22:08justin_smith#(into {} (for [[k v] %2] [k (%1 v)]))
22:09justin_smiththere we go
22:10creeseI'm having a strange issue combining component with immutant. Can someone take a look?
22:11whompnice
22:11creesehttps://gist.github.com/creese/3a6d38ffd1f2d554b21c
22:11creeseThe job function takes zero arguments but I'm still getting an exception.
22:12justin_smithcreese: you need to return a component
22:12justin_smithcreese: start and stop must both return the component
22:12justin_smitheverything breaks if you don't
22:12creesecan it be an empty map?
22:13justin_smithcreese: no it is the component that was passed in (your "this")
22:14justin_smithI mean maybe an empty map would work sometimes, but the general thing is to return the component itself
22:15creesethat may be correct, but I don't think it's my problem here
22:15justin_smithcreese: not returning a map of some sort will break component
22:15creesereturning a map doesn't solve the ArityException for Heartbeat/fn
22:16justin_smithcreese: also, the best practice is to attach something like :heartbeat :running to the component before returning it; that way you can check whether it is running already by checking that key before starting
22:16creeseok
22:17justin_smithso does schedule definitely call your job with 0 arguments?
22:17creesehow can it not?
22:17justin_smithcreese: ?
22:17creesethat's what the docs say
22:17justin_smithit could provide whatever arguments it likes, hypoethetically
22:18creese"Your "job" will take the form of a plain ol' Clojure function taking no arguments. The schedule function takes your job and a specification map as arguments."
22:18creesehttp://immutant.org/tutorials/scheduling/
22:19justin_smithOK
22:19creeseThis was working before I added component
22:19justin_smithwhat are the consequences of out-queue-group always being nil?
22:20justin_smithbecause it is guaranteed here
22:21creeseit's nill for the function?
22:21creesenot for the pprint
22:21justin_smithcreese: you don't pass in an out-queue-group
22:21creeseI can't get it through scoping
22:21justin_smithcreese: you pass in options, but out-queue-group will be nil because it is not provided
22:21justin_smithso you will publish to nil
22:21justin_smithwhich seems like it would fail
22:22creesedoesn't matter because it doesn't get that far
22:22creeseI was using partial before
22:22creesethat doesn't work either
22:23justin_smithso you are saying that (fn [] (publish! nil .....)) crashes, but it's definitely not because you are publishing to nil?
22:23justin_smithunless you are not actually using heartbeat-ctor
22:25justin_smithoh never mind, clearly you are not using heartbeat-ctor, because in the stack trace outqueue-group is not nil
22:25justin_smiththough line 15 ensures that out-queue will always be nil
22:26justin_smith,(first (filter #(= first :hearbeat) [[:hearbeat] [:hearbeat] [:hearbeat]])
22:26clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
22:26justin_smith,(first (filter #(= first :hearbeat) [[:hearbeat] [:hearbeat] [:hearbeat]]))
22:26clojurebot#error {\n :cause "Wrong number of args (1) passed to: sandbox/eval47/fn--48"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: sandbox/eval47/fn--48"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 32]\n [clojure.core$filter$fn__4578 invoke "core.clj...
22:27justin_smithso your code as written, I would expect to see that error, unless out-queue was never forced
22:27creeseupdated
22:27creesehttps://gist.github.com/creese/3a6d38ffd1f2d554b21c
22:27creeseThis is closer to the original implementation.
22:27justin_smithline 24 still guarantees that out-queue is nil
22:28justin_smithor not nil, sorry, just an invalid arity exception
22:30justin_smithcreese: " Wrong number of args (1) passed to: Heartbeat/fn--9446"
22:30justin_smiththat's the identical error I showed above
22:30justin_smithcaused by the exact line I am talking about
22:30justin_smith#(= first :heartbeat) is a function of 0 arguments that always returns false
22:31justin_smithyou want #(= (first %) :hearbeat) - which takes one arg and actually checks something about that arg
22:31justin_smithsorry, :heartbeat
22:32creesethat fn is botched, no '%'
22:32justin_smithalso, after you fix that, fix your stop implementation too - returning nil from stop prevents other components from being stopped properly
22:32justin_smithcreese: right, and thus your arity error
22:32justin_smithwhich is what caused your exception
22:33justin_smithit was just an arity error in a different function than the one you thought
22:33creeseyeah
22:33creesejava.lang.ClassCastException: clojure.lang.PersistentHashMap cannot be cast to java.util.concurrent.Future <— what does this mean?
22:34creeseI know what the first part is
22:34justin_smith,@{}
22:34clojurebot#error {\n :cause "clojure.lang.PersistentArrayMap cannot be cast to java.util.concurrent.Future"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentArrayMap cannot be cast to java.util.concurrent.Future"\n :at [clojure.core$deref_future invoke "core.clj" 2182]}]\n :trace\n [[clojure.core$deref_future invoke "core.clj" 2182]\n [clojure.core$deref invoke "core.clj...
22:34justin_smiththat's what causes that
22:34justin_smithyou tried to deref a map
22:34creeseok
22:34creeseoptions was an atom before, now it's now
22:35creesenot
22:35justin_smithbut someone seems to have tried to deref it
22:38creesepublish! does because options use to be an atom
22:38justin_smithnot needs to be?
22:38creeseI'm using component so it's just a map now
22:39creesethis is working now, thanks
22:39justin_smithawesome, glad I could help
22:39creesecomponent is pretty cool
22:39justin_smithI like it a lot
22:40justin_smithone of these days I am going to polish and share my .cljc version (it's useful on the frontend too)