#clojure logs

2015-06-04

00:23SeyleriusThere a good clojurish way to spawn virtual machines to accomplish a specific task?
00:26TEttingerhey Seylerius, did you get the sudoku solver GUI working?
00:26SeyleriusTEttinger: Been busy with errands all damn day, so no, unfortunately.
00:26SeyleriusPlanning on taking another whack at it tomorrow.
00:26TEttingercool
00:27SeyleriusOh, btw, why is your clone always hanging in here?
00:27SeyleriusTEttinger: It kinda throws off tab-completion on your nick.
00:28TEttingerTEttinger2? logger bot, I run an irc bot on an old laptop and I keep an irc client open as well so I can check if it's working
00:28TEttingererr
00:28TEttingerTEttinger2 is not actually a bot, it's the client
00:28heuristSeylerius: just set your irc client to complete based on last spoken instead of alpha.
00:29TEttingeror shortest first
00:29TEttingerbut TEttinger leaves, TEttinger2 does not
00:29TEttingerok, time to get this cluajure obscene hybrid working
00:29SeyleriusTEttinger, heurist: The problem isn't that, the problem is that it just provides the common prefix, which leaves me retyping the ": " every time.
00:30TEttingerahhhhh
00:30SeyleriusTEttinger: Cluajure? Sounds like an abomination.
00:30Seylerius(In other words, I'm being lazy)
00:31SeyleriusI'm heading out to town. See y'all later, maybe tomorrow.
00:31Seyleriusheurist: It's ERC, so I just have to configure it a little differently.
00:31SeyleriusAgain, I've been lazy.
02:44dfletcheradded my first code sample to clojuredocs.org today :) http://clojuredocs.org/clojure.core/condp#example-556fc440e4b03e2132e7d185
02:47dfletcheralso heh I never really noticed by my github qrcode thingy looks like a space invader.
02:47dfletcher*but my
02:49dfletchercondp makes all the other solutions to fizzbuzz look like a big joke heh.
02:50amalloydfletcher: not really. it's much nicer with a loop over the divisor list
02:50dfletcherexample?
02:52amalloy,(let [divisors [[15 "fizzbuzz"] [3 "fizz"] [5 "buzz"]]] (defn fizzbuzz [n] (-> (first (for [[r s] divisors :when (zero? (mod n r))] s)) (or (str n)))))
02:52clojurebot#'sandbox/fizzbuzz
02:52amalloy,(dorun (map (comp prn fizzbuzz) (range 1 30)))
02:52clojurebot"1"\n"2"\n"fizz"\n"4"\n"buzz"\n"fizz"\n"7"\n"8"\n"fizz"\n"buzz"\n"11"\n"fizz"\n"13"\n"14"\n"fizzbuzz"\n"16"\n"17"\n"fizz"\n"19"\n"buzz"\n"fizz"\n"22"\n"23"\n"fizz"\n"buzz"\n"26"\n"fizz"\n"28"\n"29"\n
02:53amalloy,(clojure.string/join " " (map fizzbuzz (range 1 31)))
02:53clojurebot"1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz"
02:55J_A_Workpersonally, my favorite FB is with javascript, because switch case can fall through, so you can write it with only the conditionals on mod 3 and 5
02:56amalloythe nice thing is that now the divisors are just data, a list you could replace without having to re-define fizzbuzz if you wanted different numbers, and the various bookkeeping is separate from the specific rules
02:57dfletcheryeah I like it. also heh thanks for zero? updated my sample
02:59lumafihow about fizzbuzz without any conditionals?
02:59lumafi,(def fizzbuzz (letfn [(fb [s k coll] (mapcat (fn [x] (cons s (rest x))) (partition k coll)))] (->> (range) (fb "fizz" 3) (fb "buzz" 5) (fb "fizzbuzz" 15))))
02:59clojurebot#'sandbox/fizzbuzz
03:00lumafi,(clojure.string/join " " (take 30 fizzbuzz))
03:00clojurebot"fizzbuzz 1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29"
03:00dfletcheractually I retract my earlier statment and ammend it. *clojure* makes other solutions to fizzbuzz look like a joke hehe
03:01amalloythat's a cute one, lumafi
03:02dfletcherzero is a weird case it matches all
03:04dfletcherwhen i tried it as an infinite seq ended up using (rest range) to start with since 0 doesn't make tons of sense
03:04dfletcher*to start with 1
03:07dfletcherman. i understood amalloy's one pretty quick. this one is making me look up thinigs and I still have no idea whats going on heh.
03:08amalloydfletcher: do you want a hint or to figure it out yourself?
03:08dfletcheri like a puzzle i'll ask if I want help hehe
03:10dfletcherthanks for asking though rather than just answering it. just feeling chatty this eve :)
03:12mmeixBeginner's question: I have [ {:a 1} {:a 2} {:a 3} {:b 5} {:b 6} {:c 99} ] and I want to get [ {:a [1 2 3] {:b [5 6]} {:c [99]} ] - what would be the fn to use with merge-with in this case?
03:12mmeix(obviously conj and concat etc wouldn't work)
03:13TEttinger(doc merge-with) ; let's see...
03:13clojurebot"([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."
03:13amalloymmeix: in fact concat does work (though i recommend into instead), as long as you pre-process the sequence ahead of time
03:14mmeixah, ok
03:14amalloytry something like this: (apply merge-with into (for [m [{:a 1} ...]] ...))
03:15mmeixok, wrapping my brain around this - thanks!
03:29benhudahello
03:30benhudado you think it is wise to name an open source library "kevlar" given that Kevlar is registered trademark?
03:31amalloywell on the one hand you would be safeish on trademark infringement, since there is no danger of someone confusing your clojure library for actual physical kevlar. on the other hand there's nothing stopping them from suing you anyway
03:31benhudayes i just bumped into some lawsuit for kevlarftp (OSS) which was named to kftp after lawsuit threats
03:33benhudai'll just call it 'armor' then :)
03:35dfletcheroh oh I get it! partition is breaking it into sets of 3,5,15. then replace the first element of each partitioned bit with the string. then cons to stitch it all back together. genius! thanks for that lumafi
03:36TEttingerkavler
03:36TEttingercavalier
03:39dfletchererr, mapcat to stitch it back together, cons is doing the string replacement thingy. ok after midnight i'm a pumpkin now. night peeps.
03:44TEttinger&(let [r (range 100) matching (fn [n s] (map #(if (zero? (mod % n)) s "") r) fizz (matching 3 "fizz") buzz (matching 5 "buzz") fizzbuzz (map str fizz buzz)] (map #(if (empty? %1) %2 %1) fizzbuzz r))
03:44lazybotjava.lang.RuntimeException: Unmatched delimiter: ]
03:44TEttingeraww
03:45TEttinger&(let [r (range 100) matching (fn [n s] (map #(if (zero? (mod % n)) s "") r)) fizz (matching 3 "fizz") buzz (matching 5 "buzz") fizzbuzz (map str fizz buzz)] (map #(if (empty? %1) %2 %1) fizzbuzz r))
03:45lazybot⇒ ("fizzbuzz" 1 2 "fizz" 4 "buzz" "fizz" 7 8 "fizz" "buzz" 11 "fizz" 13 14 "fizzbuzz" 16 17 "fizz" 19 "buzz" "fizz" 22 23 "fizz" "buzz" 26 "fizz" 28 29 "fizzbuzz" 31 32 "fizz" 34 "buzz" "fizz" 37 38 "fizz" "buzz" 41 "fizz" 43 44 "fizzbuzz" 46 47 "fizz" 49 "buzz" "fizz... https://www.refheap.com/102078
03:45TEttingerit's always nice to write fizzbuzz
03:46TEttingerdifferent ways every time
03:51H4nshow can i, in cider, achieve that a macro expansion (C-c C-m) is not elided using #?
03:51H4nsC-c M-m that is
05:28kungiI updated compojure from 1.2.0 to 1.3.4 and the order of the keys/vals in (:roles (friend/current-authentication)) reversed?
05:29kungiO.o
05:30Empperikungi: you cannot rely on map value ordering
05:30Empperinot unless you are using a sorted map
05:30Empperihttps://clojuredocs.org/clojure.core/sorted-map
05:31TEttingeror an ordered map, which doesn't come with clojure and is in flatland
05:31kungiEmpperi: not the ordering of the map. The keys and values reversed
05:31kungiKeys are now values and the other way around
05:31TEttingerhm
05:31Empperiwell that sounds strange
05:32TEttingerthat would break all sorts of things if there were duplicate values before: ##(hash-map :a 1 :b 1)
05:32lazybot⇒ {:b 1, :a 1}
05:32TEttingertotally fine, but
05:32TEttinger##(hash-map 1 :a 1 :b)
05:32lazybot⇒ {1 :b}
05:32TEttinger,{1 :a 1 :b}
05:32clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: 1>
05:33TEttingerthe function hash-map is more lenient than the literal
05:38kungi... I think it's my fault because of my get-roles-for-user function ...
05:40ionthas_What is the neatest way to define default values for a function? Right now I'm using arity and I call the function with the default parameter value.
05:41Empperithat is pretty much the neatest way except if you pass in a map and want to provide default values for keys
05:41Empperi,((fn [{:keys [foo bar] :or {foo 1 bar 2}}] [foo bar]) {:foo 15})
05:41clojurebot[15 2]
05:42Empperiin that case it's better to use that part of destructuring syntax
05:42Empperias one might expect, works everywhere where destructuring works
05:43ionthas_Thanks Empperi :)
05:43Empperinp
05:45danielcompton@cfleming: you around?
05:48kungiFound it!
05:52mmeixamalloy recommended "into" instead of "concat" for use in merge-with - what are the advantages of into vs. concat?
05:52mmeix(besides looking neat)
05:52justin_smithmmeix: hash-maps are strict, concat is lazy
05:53justin_smithit's usually a bad idea to mix strict and lazy unless you have a specific reason to
05:53mmeixI see
05:53justin_smithsee also stuartsierra's blog post on concat
05:54justin_smithhttp://stuartsierra.com/2015/04/26/clojure-donts-concat
05:54mmeixIf I'm foreseeing, that I will consume the whole data, lazyness buys me nothing inthis case - right?
05:54justin_smithright
05:54mmeixah - thanks for the article!
05:54justin_smithunless the data is too large to be in memory all at once
05:55justin_smithmmeix: it's a good blog to follow for clojure
05:55mmeixmy data is mostly around 5-20 elements
05:55justin_smithyeah, staying strict will keep it simpler than
05:55justin_smith*then
05:55mmeixgreat advice, as ever :-)
06:00kungiEmpperi: you where right. I depended on the order of entries in a map. It was a bit hidden in the code
06:01cflemingdanielcompton: Yep, what's up?
06:02kungiIs there a standardlibrary function to (select-vals {:a 1 :b 2 :c 3} [:a :c]) -> [1 3]
06:07mmeixI have a second question, loosely related: for my current project (music typesetting with svg in clojurescript) I built a couple of basic functions, and a bigger one, which uses them to build a combined graphical group (a chord, consisting of several noteheads, accidentals, stem flags/beam, dots etc.) with many calculations in it, depending on each other; this makes sense as a semantic unit and building block for the next higher
06:07mmeix level. Now for spacing several of these units in a row (staff) I need to ask the group about its dimensions, which would have to be calculated out of the elements in it - this begins to sound like an object with a function "return-size" or something like that in it. What would be a proper Clojure solution to expose this to the next higher function?
06:12mmeix, (map {:a 1 :b 2 :c 3} [:a :c])
06:12clojurebot(1 3)
06:12mmeix(for kungi)
06:12justin_smithalternately ##((juxt :a :c) {:a 1 :b 2 :c 3})
06:12lazybot⇒ [1 3]
06:13TEttingerjuxt!
06:13TEttingerjuxtin_smith
06:13kungimmeix: justin_smith thank you :-)
06:13TEttinger(inc mmeix)
06:13lazybot⇒ 1
06:13TEttinger(inc justin_smith)
06:13lazybot⇒ 258
06:13mmeixmy first inc :-)
06:13justin_smithTEttinger: eventually I will have to implement juxt-in
06:13TEttingerthis-juxt-in
06:14justin_smiththat's the version for protocols, of course
06:14ddellacostaomg
06:14ddellacostayou guys are such dorks
06:15justin_smithmmeix: are the graphical elements nested like a tree? if so you may want to do a tree walk and either a thing knows its width, or can find out the width from its children, recursively
06:16mmeixthey are not nested, but dependent on each other via some rules for placement
06:16justin_smithmmeix: oh, then that sounds like a reduce
06:17justin_smitheach one figures out what its right edge in, based on the prior state, and passes that forward
06:17justin_smiths/in/is
06:17mmeixaha ... have to ponder this for a while ...
06:19mmeixthat means, my group has to collect these measurements inside in a neatly accessible way, and expose it as an additional return value, in a map or something like this)
06:21mmeixand since I'll need the dimensions anyway, the "object" should calculate it alongside all the placement and return it with them - is this right thinking?
06:21justin_smithI think so
06:21mmeixok - thanks!
06:24mmeixdoes anyone have a good source for algorithms for overlap detection of shapes (consisting of horizontal/vertical straight lines only)?
06:25mmeix(expressed in x/y coords, of course)
06:26TEttingerif the line is vertical, check if its x is between the end and start of any horizontal lines, and if its x is identical with any other vertical lines
06:26TEttingerif the line is horizontal, check if its y is between the end and start of any vertical lines, and if its y is identical with any other horizontal lines
06:27mmeixand do this for any combination ...?
06:27mmeixI see
06:27TEttingerI mean that's super naive, but each check should be very fast
06:27TEttingeryou can end early if you're doing a reduce, see ##(doc reduced)
06:27lazybot⇒ "([x]); Wraps x in a way such that a reduce will terminate with the value x"
06:28TEttingerso if you know you overlap, you don't need to keep checking
06:28mmeixI didn't know about early ending in reduce
06:28mmeixmore to learn
06:28mmeixthanks again
06:30justin_smithyeah, it's easy to get it mixed up, because we have something called "for", but reduce really ends up being the idiomatic replacement of for in other languages in most cases
06:31mmeixI get the notion, that for is seldomly the best solution in Clojure
06:31mmeixusing map and reduce instead
06:31justin_smithit's useful, but I think people get misled by the name about what it would be good for
06:32TEttingerfor is often a good solution, but it's "for" generating sequences that you usually want to end up changing with map, reduce, filter, etc.
06:33mmeixI see - "reduced" is my finding of the day ...
06:33mmeix(inc TEttinger)
06:33lazybot⇒ 57
06:34mmeix(inc justin_smith)
06:34lazybot⇒ 259
06:35TEttingergotta inc justin
06:36mmeixwhich I did :-)
06:36TEttingeryeah, but it's basically becoming a rule now that technomancy isn't showing up here
06:36TEttinger(identity technomancy)
06:36lazybottechnomancy has karma 163.
06:36TEttingerwow
06:36TEttingerhe used to be King Karma
06:37justin_smith(identity amalloy)
06:37lazybotamalloy has karma 276.
06:37TEttingerI guess he's still garnering good karma, just uh not bot karma
06:38mmeixlast question:
06:39mmeix,(let [m [1 4 2 7 8 5] ] ((juxt min max) m)
06:39clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
06:39mmeixumpf
06:39mmeix;(let [m [1 4 2 7 8 5] ] ((juxt min max) m))
06:39justin_smithso close!
06:40mmeix,(let [m [1 4 2 7 8 5] ] (apply (juxt min max) m))
06:40clojurebot[1 8]
06:40mmeixvs.
06:43mmeix,(let [m [1 4 2 7 8 5]] ((juxt first last) (sort m)))
06:43clojurebot[1 8]
06:43mmeixhas one of these an advantage?
06:44TEttingeryeah
06:44mmeix(if this would be needed a lot of times)
06:44TEttinger,(let [m ["the" "quick" "brown" "fox"]] ((juxt first last) (sort m)))
06:44clojurebot["brown" "the"]
06:44TEttingermin and max are number only
06:44mmeixah!
06:45mmeixdidn't think of that
06:45TEttingerso sort will have better behavior if you need to change it to another comparable type
06:45mmeixin my case I have only numbers
06:45justin_smithwe have max-key and min-key
06:45justin_smith(doc max-key)
06:45clojurebot"([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."
06:46tvanhensI'm having some difficulty wrapping my head around how protocols work in the repl. I have a dsl ns that has various records that implement the same protocol in a protocols ns. Then I have another ns called api that checks to see if the records passed into a function satisfy the protocol in the protocols ns but all the inputs are returning false even though when I call type on the inputs they are returning the proper record type which does implement the
06:46tvanhens protocol I am checking for. If I manually evaluate the nses in a different order (dsl first then protocols then api) it works as expected.
06:46justin_smith,(let [m ["the" "quick" "brown" "fox"]] ((juxt (partial apply max-key count) (partial min-key count)) m))
06:46clojurebot["brown" ["the" "quick" "brown" "fox"]]
06:46justin_smithoops
06:47justin_smith,(let [m ["the" "quick" "brown" "fox"]] ((juxt (partial apply max-key count) (partial apply min-key count)) m))
06:47clojurebot["brown" "fox"]
06:47mmeixgreat stuff!
06:51j-pb,(let [m ["the" "quick" "brown" "fox"]] (apply (juxt (partial max-key count) (partial min-key count)) m))
06:51clojurebot["brown" "fox"]
06:52mmeixjuxt as the ultimative extractor
06:53mmeix(learning Clojure is really fun)
06:53tvanhensit appears that for some reason the namespaces are loading in a weird order and the only way I can get around the behavior is to manually evaluate my namespaces in the right order. Whats weirder is that the problem does not occur when I run my program with lein run or run the tests with lein tests
06:54tvanhensit appears that the strange protocol behavior only occurs when I am in the repl
06:54TEttingerwhat's amazing is that the code in there is practically all function calls with names, and almost all of those are defined in clojure. nothing like in java or C or C++ with for(int i = 0; i < 10; i++)
06:54justin_smithtvanhens: sounds like you are not requiring something you should be?
06:54j-pb,(let [m ["the" "quick" "brown" "fox"]] (apply (partial (juxt max-key min-key) count) m))
06:54clojurebot["brown" "fox"]
06:55j-pbthis also works, but at this point my brain stops properly comprehending whu
06:55justin_smithj-pb: ahh, much better
06:55justin_smithheh
06:55tvanhensI think that might be the case justin_smith hard to track it down when the tests are passing
06:55justin_smithtvanhens: it's true I am hard to track down when the tests are passing
06:56justin_smith(I know that's not what you meant)
06:56tvanhenshaha :)
06:56TEttinger(inc j-pb)
06:56lazybot⇒ 1
06:56TEttingerthat's a nice golf solution, j-pb
06:57j-pbTEttinger: got to think about it some more to make sure it's correct though ;)
06:57tvanhensyeah its funky cause the system will start with lein run with no problems. What might cause there to be a discrepency between the two? Its almost as if the repl is using a different protocol even though its the same definition
06:57j-pbbecause right now, the transformation seems correct, but not really intuitive :D
06:57justin_smithtvanhens: with the repl are you using the same top level namespace that lein run is?
06:57mmeixa bit of brain twister, yes
06:57hyPiRionpsst
06:57hyPiRion,(let [m ["the" "quick" "brown" "fox"]] (apply (juxt max-key min-key) count m))
06:57clojurebot["brown" "fox"]
06:58hyPiRionno need for partial there
06:58mmeixwow
06:58tvanhensno. I will try doing that with repl options
06:59tvanhensactually scratch that... it is loading into the same top level namespace
06:59justin_smithanother possibility is any classpath differences between your profiles
07:03tvanhensinteresting ok so if I restart my repl and then try to eval the user ns or the core test ns I get an error that the records do not satisfy the protocol. However, if I reset my system with stuart sierra (wich uses refresh for ns-es) I can eval either of those two ns-es fine
07:04TEttingerI have a feeling you mean one of stuart sierra's libraries, not the person who often is in here
07:04justin_smithtvanhens: are things being required in the wrong order?
07:05justin_smithTEttinger: he has stuartsierra in another room, when he gets the signal he reloads all the namespaces
07:05j-pbhyPiRion: haha very nice, actually using the apply that way make it quite abit more intuitive :D
07:05j-pb(inc hyPiRion)
07:05lazybot⇒ 75
07:05tvanhenshaha if only
07:06mmeix[light bulb] re: juxt "The returned fn takes a variable number of args" - that made my day
07:06justin_smithTEttinger: tvanhens also this reminds me I need to make the tests pass on my port of component to cljc so I can share it (it totally works in my dev code so far, using it for a while now)
07:06mmeixthanks guys!
07:06tvanhensyeah it looks like they are getting required in the wrong order but only in development. The only difference in the classpath is adding a user and a utils ns when in dev... must be related to those
07:06j-pbmmeix: yeah, but actually this is what makes them a tad slower :D compared to #(foo %)
07:07j-pbnot significantly though
07:07j-pbspeaking of which, am I the only one really missing a #` reader macro? that would combine #() and `[] ?
07:07tvanhensjustin_smith: that would be great
07:07mmeixso readabilty/understandability wins in this case :D
07:09TEttingerj-pb, so it is anonymous fn syntax that produces a quoted list?
07:09TEttingererr, syntax-quoted
07:10j-pbTEttinger: yeah exactly, the ` syntax quote already produces a set of function call to build the described structures, but you can't use it in a #() form because of the immediate function call
07:10TEttinger,`'#(+ % %)
07:10clojurebot(quote (fn* [p1__25__26__auto__] (clojure.core/+ p1__25__26__auto__ p1__25__26__auto__)))
07:11TEttinger,`~'#(+ % %)
07:11clojurebot(fn* [p1__51#] (+ p1__51# p1__51#))
07:11TEttingerwheeeeeee
07:11TEttinger,(`~'#(+ % %) 2)
07:11clojurebot#error {\n :cause "clojure.lang.PersistentList cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval77 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval77 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "...
07:11TEttingerwowza
07:11justin_smith,`~`~`~`~'#(constantly nil)
07:11clojurebot(fn* [] (constantly nil))
07:12justin_smith,`~`~`~`~`~`~`~`~`~`~`~`~`~'#(constantly nil)
07:12clojurebot(fn* [] (constantly nil))
07:13tvanhensoy this is annoying. Ok so test-refresh works (which is using the dev profile) lein run works (which is using prod). Starting the repl goes ok. But if I try and run the tests in the test ns without restarting the system... it won't work. Or if I try evaling the user ns. Any other ideas? I guess its pretty simple to workaround but not understanding whats going on is eating at me
07:13TEttinger,(defmacro whee [anon] `~anon)
07:13clojurebot#'sandbox/whee
07:13TEttinger,(whee #(+ % %))
07:13clojurebot#object[sandbox$eval177$fn__178 0x4ae63a85 "sandbox$eval177$fn__178@4ae63a85"]
07:14TEttinger,((whee #(+ % %)) 2)
07:14clojurebot4
07:14TEttingerwoo
07:14j-pbhrhr
07:16j-pbbut yeah, I find myself quite often in a situation where I would like to map over some data and transform each element to some datasructure, a #` would tremendously help with that
07:17justin_smithj-pb: I still don't see where syntax quote helps build data structures
07:18j-pbjustin_smith: when you deal with xml/html trees, variants or maps representing some kind of record it's really usefull
07:19j-pbjustin_smith: mostly because of its splicing capabilities
07:19j-pbjustin_smith: ~@x is the inverse operation for & x
07:21gfredericksI always thought list* was
07:21j-pbTEttinger: ah sorry I think I missunderstood you, it would be a syntax for producing a function that takes args and returns a datastructure with the arguments embedded at some places
07:22crocket(slurp cat)
07:22j-pb,(macroexpand '`[:foo %1 %2])
07:22clojurebot(clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list :foo) (clojure.core/list (quote sandbox/%1)) (clojure.core/list (quote sandbox/%2)))))
07:22j-pb,(macroexpand '#(`[:foo %1 %2]))
07:22clojurebot(fn* [p1__49# p2__50#] ((clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list :foo) (clojure.core/list (quote p1__49__51__auto__)) (clojure.core/list (quote p2__50__52__auto__)))))))
07:23j-pbwhile #`[:foo %1 %2] would return basicall y #(clojure.core/apply clojure.core/vector (clojure.core/seq ...
07:24mmeix( followup question: would something like "(apply (juxt max-key min-key) count ...)" a use case for a transducer? )
07:25mmeix(potentially a silly question, I fear ...)
07:25j-pbgfredericks: yeah kinda, but that is what syntax quote will just generate, right? manually building the function calls to generate the datastructures is a lot less obvious than syntax quote
07:26j-pbmmeix: could you explain further?
07:26gfredericksj-pb: yeah if it does what you need I guess you may as well use it
07:26mmeixI'm not sure .... sorry .... does (apply (juxt max-key min-key) count m) generate intermediate lists, internally?
07:27j-pbmmeix: no
07:27mmeixah, ok, then the question was silly :D
07:29mmeix(partial (apply (juxt max-key min-key) count)) could make sense, OTH, maybe ...
07:29j-pbmmeix: well the strings will be cast to a sequence, for count probably, and the apply might turn the input vector to a seq as well
07:29j-pbwould have to be (partial apply (juxt max-key min-key) count)
07:29mmeixok
07:29mmeixja
07:31mmeix(inc j-pb)
07:31lazybot⇒ 2
07:53zamaterianikitommi_, should I try to implement a pull request for isssue #121 - that moves the validation into a couple of middleware, as described in my comments ?
08:17crocketRuby map's rehash method terrifies me.
08:17crocketIt leads to all sorts of bugs.
08:17crocketMutation is bad.
08:19TEttingercrocket, if rehash terrifies you, you should see another ruby method, vomit-spiders
08:19tdammersis that like Haskell's hypothetical unsafeLaunchMissiles?
08:19TEttingerhehe
08:21TEttingervomit-spiders is an interesting function in ruby's standard lib. they don't know when the commit was, but it was before 1970 so the exact time is hard to guess. the comments are in aramaic though.
08:23TEttingerthe author's name also appears to be permanently lost, since anyone who claims to have decrypted the thousands-of-characters-sequence speaks in tongues for a while then never speaks again.
08:23TEttingerwhich is something of a liability to a large software team
08:25TEttingerbut it hasn't been removed from the standard lib because Matz has implied that to do so would be very bad if "the stars are not yet right, and the sleeping multitudes have not yet awoken from their dreaming complacency and seen the fire and heard The Screams."
08:25crocketWhat is vomit-spiders?
08:26TEttinger$google creepypasta
08:26lazybot[Creepypasta] http://www.creepypasta.com/
08:26tbaldridge~guards
08:26clojurebotSEIZE HIM!
08:26tbaldridgecrocket: do no speak of this again
08:26crockettbaldridge, this?
08:27crocketI need a clarification of what 'this' refers to.
08:28TEttingerhumor
08:30crocketClojure's data abstractions are as soothing as my aftershave.
08:37crocketHeisenbugs...
08:46crocketIn the land of ruby and java, you'll see heisenbugs...
08:54crocket,(map inc [1 2 3])
08:54clojurebot(2 3 4)
08:54crocket,(doc join)
08:54clojurebotGabh mo leithscéal?
08:56crocket(clojure.string/join ["s" "e" "x"])
08:56crocket,(clojure.string/join ["s" "e" "x"])
08:56clojurebot"sex"
09:19crocketHow would you allocate memory on JVM?
09:19crocketWithout aggressive GC, I'm not comfortable.
09:28profilwhy is there no multiple bind version of if-let? sorta like how some-> works
09:31crocketprofil, Did you ever need a multiple bind version of if-let?
09:36profilyes, I find it ugly to nest multiple if-lets
09:36H4nsi've also wanted that in the past.
09:36hyPiRionNesting if-lets won't give the same functionality as having a multiple-bind if-let
09:36crocketprofil, Why don't you make one?
09:36profilhyPiRion: what do you mean? some-> threads sequentially when the result is not nil
09:36H4nsjust because you can add general language-level to clojure does not necessarily mean that it is a good idea to do so.
09:36Empperihmm, that sounds more like what "some-let" should be, not multiple binding version of if-let
09:36profilI think scheme has what I want, called and-let
09:36Empperi"bind these expressions into let constants as long as the previous binding ended up into something else than nil, then execute the body with those constants available"
09:36Empperiif I got it right
09:36crocketYou should be able to write cond-let.
09:36crocketcond is what you want.
09:36profilEmpperi: yes, by using something like (and ~@binds)
09:36Empperipretty easy to do with some macro magic
09:37hyPiRionprofil: (if-let [a b] (if-let [b c] foo bar) baz) is different from (if-let [a b c d] foo baz)
09:37profilcrocket: no, I dont care about which one failed
09:37profilhyPiRion: there is no (if-let [a b c d] foo baz) ...
09:37chouseractually, that's interesting. cond-let and and-let both sound plausible but would have different semantics.
09:38crocketprofil, What do you want to do?
09:38chousers/actually,//
09:38hyPiRionprofil: the point is, even if there were, multiple-binding if-let wouldn't be the same as nested if-lets
09:38Empperidefinitely, but I can see the use case for what I just described above
09:39hyPiRionyeah, sure thing
09:42crocketprofil, Can you give us a paste of a minimal nested if-let form?
09:42crocketI may be able to simplify your code.
09:57crocketIf you don't care about which one failed, you should nest an if form inside a let form.
09:57crocketThis is simpler.
09:58H4nscrocket: it is also not the same thing
09:59H4nscrocket: because when if-let allowed multiple bindings, i would expect it to not evaluate bindings further down as soon as an initialization form returned a false value
09:59hyPiRion(let [a b c (and a d) e (and c f)] (if f foo bar))
10:00crocketWe need to see an actual problem case.
10:00H4nsbeautiful
10:00chousersounds like nested when-let to me
10:00hyPiRionif is probably better to use than and actually.
10:00hyPiRiongives same result, but might be easier to read? idk
10:01chouserah, you want one else for any falsey. hm.
10:02profilI was thinking of something like "(defmacro and-let [bindings then else] (let [tests (take-nth 2 (rest bindings))] `(if (and ~@tests) (let ~bindings ~then) ~else)))"
10:02chouseryeah, and you want 'if' instead of 'and'
10:02Bronsaif-lets
10:02H4nsprofil: nice
10:03crockethttps://gist.github.com/pingles/5150585
10:03chouserprofil: good sketch, clarifies things. But runs expressions twice.
10:03profilyeah, I havent tested it
10:04crocketprofil, ^^
10:06chouservery interesting attempts. Even the last one in the comments there copies the else clause multiple times in the expansion, though only runs it once.
10:06crocketWhy doesn't clojure already provide a proper let binding for if-let?
10:08crocketI mean multiple local bindings should be available in if-let.
10:09hyPiRioncrocket: I believe it's because it's not evident what the evaluation rules would be. Given (if-let [a b c d] foo bar), should c be evaluated if a is falsey? If so, then it's "inconsistent" with all the other binding forms out there.
10:09hyPiRionEr, I meant the opposite
10:10crocket"consistent"
10:10hyPiRionI meant: If c is not evaluated if a is falsey, then it would be inconsistent with the other binding forms
10:11chouser(if (when-let [a b] (when-let [c d] (when-let [e f] ~then))) ~else)
10:11chouseris that it?
10:12crocketThat is ugly
10:12crocketdifficult to read
10:13chouserWell, I appreciate the input. I was asking if the semantics match what is desired.
10:13crocketchouser, That's what I had in mind.
10:14H4nschouser: if then returned falsey, else would be evaluated and returned. that's not right.
10:14chouserH4ns: ah, great catch.
10:17chouserok, so hyPiRion's solution, but with 'if' instead of 'and' looks best so far
10:19crocketnested if-let sounds nasty.
10:19H4nscrocket: if it is only in macroexpansion, what would be wrong with it?
10:19crocketIs this a deal breaker?
10:20crocketH4ns, Can you show me the macro?
10:21hyPiRioncrocket: https://gist.github.com/pingles/5150585#comment-981238, was it not?
10:21H4nscrocket: i have not written it because in my opinion, it is not right to add semantics to the language at that level. i do think, though, that it would be the easiest path towards a correct solution. i understand the argument that it would be inconsistent with other clojure binding forms if if-let did not always bind all variables, so i'm okay with not having it.
10:22tbaldridgeyou aren't really adding semantics, it's adding syntactic sugar.
10:22H4nstbaldridge: same thing to me.
10:23tbaldridgeI'm just saying, don't be afraid to use the features of LISP. They're there for a reason, and used correctly they can offer great power.
10:23H4nstbaldridge: that kind of stuff always reminds me of "#define BEGIN {" back in the day
10:24crocketThat duplicates else multiple times.
10:24H4nstbaldridge: well yeah right. and in the end, i always prefer conventional code to sugar-coated
10:24tbaldridgesuit yourself, but remember, when is a macro implemented in user code (not in the compiler), same with if-let, if-some, and, or, etc.
10:25tbaldridgeThe compiler only implements about 12 special forms, everything else is syntactic sugar.
10:26H4nstbaldridge: that is just implementation detail. i don't care about the implementation. all i want is that if i see a common control flow or branching form, i can look into the language manual to see how it works.
10:27crocketI think I'll get back to it later when it becomes a problem.
10:27tbaldridgebut that's what (doc 'foo) and (source 'foo) are for.
10:28tbaldridgeI mean, if you don't want to use macros, that's fine, but just realize you'll be coding lisp with one hand tied behind your back.
10:28H4nstbaldridge: i'm using macros all day long, just not to add syntactic sugar for basic language features that i thing should be "better".
10:29H4nstbaldridge: i think you can stop trying to evangelize me. :)
10:29chouserthis channel has a bad influence on my responsible use of time :-P
10:31chouserdestructuring forms cause a bit of a problem with hyPiRion's formulation
10:33hyPiRionOh, I've never thought about destructuring binds in if-lets :o
10:34hyPiRion,[(if-let [[a b] [nil nil]] 10) (if-let [[a b] nil] 20)]
10:34clojurebot[10 nil]
10:34hyPiRionHrm, I'm not sure what I expected for the first one.
10:35chouserwell, that's how it's always been. I take advantage of that at times
10:35chouserelse is only for the *expr* being falsey. Nothing to do with the bound locals.
10:35hyPiRionright
10:36chouserbut for multiple-binding-if-let, you can't feed nil to users destructuring forms without risking an exception
10:36chouser...an exception that they may have been trying to guard against by using if-let :-P
10:37chouserBut you can't wait and do the destructuring just before the ~then because of course they may be using the bound locals along the way
10:38hyPiRionI guess (let [g1# b, a g1#, g2# (if g1# d), c g2#] (if g2# then else)) would work
10:38hyPiRionbut that looks convoluted
10:38chouserno, that's what I'm saying won't work
10:39chouserif b is nil, c will be fed a nil.
10:39chouserIf c is a destructuring form that blows up on nil, you'll get an exception instead of the else
10:40hyPiRionooh
10:40chouserer, there are destructuring forms that blow up on nil, right?
10:41chousermaybe not. There are destructing forms that blow up, but maybe none with nil.
10:41hyPiRionI think you can if you expect the form to be of some shape
10:42hyPiRion,(let [{foo :foo bar :bar :or {bar (+ foo 10)}} nil] bar)
10:42clojurebot#error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [clojure.lang.Numbers ops "Numbers.java" 1013]}]\n :trace\n [[clojure.lang.Numbers ops "Numbers.java" 1013]\n [clojure.lang.Numbers add "Numbers.java" 128]\n [clojure.lang.Numbers add "Numbers.java" 3644]\n [sandbox$eval54 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]...
10:42hyPiRion,(let [{foo :foo bar :bar :or {bar (+ foo 10)}} {:foo 10}] bar)
10:42clojurebot20
10:42chouserah, :or ... excellent
10:43hyPiRionHeh, macros are hard to get right.
10:43chousertrying to expand the else clause exactly once makes this quite tricky
10:44chouseryou could wrap it in a function, I suppose. But that loses its tail position in the containing form. sheesh
10:46chouserMaybe mutating a local flag is the best way. Huh.
10:57phillordI'm just trying nightcode out and it seems to be sending my system load through the roof...anyone else had the same experience
11:01gfredericksI wrote a basic test.check property testing carmine message queues and immediately ran into a connection pooling quasi-bug https://github.com/ptaoussanis/carmine/issues/135
11:01gfredericks(inc test.check)
11:01lazybot⇒ 1
12:07mikerodI'm struggling to remember what puredanger blog is now
12:07mikerodsomething like "inside a clj developer" - my google searching is failing
12:10mikerodhttp://insideclojure.org/
12:10mikerodgot it
12:15CookedGryphonHey, I want to download zip files in my application from multiple end points, with associated names and version numbers... this sounds a lot like artifact dependency management. Does anyone know if there's a light weight artifact download/cache management client library that I could bundle with my app?
12:18dfletcherhttps://github.com/cemerick/pomegranate CookedGryphon maybe?
12:18dfletchermorning all
12:19alexyakushevDoes anyone have suggestions how to use gen-class in tests?
12:20tbaldridgeI don't know that you can, gen-class requires AOT compilation, don't think that works with most test suites
12:23alexyakushevtbaldridge: That's what I thought. I'm trying to run compile step before testing now, let's see if it works
12:24mikerodDoes anyone know of a good post anywhere that compares operations on Clojure transients to some mutable Java types - like Arraylist and then even primitive arrays?
12:24mikerodI was doing some microbenches locally with criterium and not getting the expected results (transients were faster)
12:24mikerodjust doing something basic like, conj'ing up a vector
12:25mikerodwith longs
12:25tbaldridgewhat java collection were you using/
12:25tbaldridge?
12:25tbaldridgenvm, just read what you said
12:25mikerodI tried PersistentVector vs transient PersistentVector vs ArrayList vs Primitive array
12:25mikerodI'm thinking I'm just writing something stupid, but I was hoping to find some solid resource online
12:25mikerodwhere someone already gives a good rundown
12:25tbaldridgesome code would be good
12:26mikerodI'll get some up shortly to demo
12:26tbaldridgeIt could just come down to default sizes of things in Java. transient vectors allocate data in chunks of 32. So it might be possible that ArrayList is using something different
12:28tbaldridgeAlso, array lists must copy all contents every time they resize, while vectors allocate in chunks and don't copy old chunks when creating new. ]
12:28tbaldridgeSo there's a lot of things here that could cause what you're seeing
12:48franklnrswhen using reagent, is it idiomatic to keep the complete app state in a single atom and have event handlers do deeply nested update-ins?
12:50dnolenfranklnrs: you should probably direct your question to #clojurescript
12:51franklnrsah yes, will do
12:51dnolenfranklnrs: Reagent supports both dividing up your state into multiple ratoms and an Om style single atom + cursors.
12:51justin_smithfranklnrs: I don't think you would need "nested update-ins" - one update-in with a deep nesting of keys maybe...
12:52justin_smithunless I misunderstand you here
12:52franklnrsand things won't be rerendered multiple times when they depend on multiple ratoms?
12:53franklnrsjustin_smith, you're right, update-in with deep nesting of keys
13:10mikerodtbaldridge: thanks for the input
13:10mikerodsorry, I had to step away a few. I have https://www.refheap.com/102091
13:10mikerodthere is a good chance I just did something wrong in the loop-recur examples, but I don't see where the issue would be
13:11mikerodI was also surprised peek-pop traversal of the vector wasn't as fast as first-next - but not completely relevant
13:12tbaldridgemikerod: they're slow because you're using first/next to access the vector
13:13tbaldridgeyour first two examples are using the .reduce method on the input vector, this will always be much faster, as it doesn't allocate lazy-seq cells.
13:14tbaldridgemikerod: your first two examples eventually call this method: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java#L328
13:14tbaldridgethat'll be much faster than first & next
13:15tbaldridgeSo I'd recommend refactoring the ArrayList example to use reduce. Keep the array list in the accumulator, and call .add on it with each item given to you.
13:19dysfunwhen i deploy an uberjar to my server and java -jar, i get an error saying my core class cannot be found. i've just looked inside the jar and there are AOT versions and the clojure source as well. the named main class is correct. any ideas?
13:20dysfunit's built with leiningen
13:21hiredmandysfun: is the main class specified in the manifest?
13:23dysfunyes, Main-Class is correct in the manifest
13:24hiredmanand what happens if you run java -cp your.jar your.main.Class
13:25dysfun"Could not find the main class: my.app. Program will exit"
13:25hiredmanhow sure are you that the class exists in the jar?
13:26dysfunzip -Tv | grep -v warning | less
13:26dysfuner + the jar filename
13:26hiredman(zgrep)
13:26dysfunooh, handy
13:26hiredmanfirst thing to do is to blow away target or classes for lein to make sure nothing stale is in there
13:27dysfunthere isn't anything stale because i don't have leiningen on the target machine
13:27hiredmandysfun: on the build machine
13:28dysfunokay, it'll take a minute to build and push
13:28hiredmanthe class reported in the "could not find the main class" error exactly matches your main class?
13:28dysfunokay, now i get "Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method.
13:29hiredmanthere you go
13:30dysfunright, so i've got :main ^:skip-aot my.app and :profiles {:uberjar {:aot []}}
13:31dysfunif i don't disable aot, i get build errors
13:31dysfuni think it's to do with running clojure-1.7.0-beta3
13:31justin_smithdysfun: my usual approach is to either use clojure.core as my main (supplying my ns as an arg) or make a very tiny namespace that implements the right magic for jsvc, and use require at runtime, plus resolve, to invoke my stuff dynamically after loading
13:31hiredmanwell, like, fix your build
13:32dysfunhrm, i could require at runtime, that could work
13:32justin_smiththat avoids the issues that come with aot
13:32hiredmanyour build just sounds broken, I would wipe as much as possible from your project.clj and get it working from a clean slate
13:32dysfunwhile fixing it all would be lovely, i've already spent ages fiddling with toolchain
13:33dysfuni suppose i probably don't need clojure 1.7 any more now i stopped using the latest clojurescript
13:37mikerodtbaldridge: I thought so, but I'm not exaclty sure what my alternatives are
13:38mikerodtbaldridge: oh ok
13:38mikerodI didn't see your second post
13:38mikerodI was skeptical of the first/next stuff
13:41mikerodtbaldridge: I also tried iterating over an ArrayList.get() instead of a PersistentVector
13:41mikerodIt still looked like transients win
13:42tbaldridgemikerod: the accessing is muddling your results I think. Perhaps just rewrite them all to use a loop with a counter instead of (vec (range ...))
13:42mikerodhttps://www.refheap.com/102093
13:43mikerodtbaldridge: good point
13:43tbaldridgeThen you're not "complecting" the testing of access with creation.
13:43mikerodI figured thesse were just sloppy comparisons
13:43mikerodthrew it together quick to try to gauge when it really matters if you are using a mutable Java collection vs transient vs persistent immutable
13:44mikerodThen I started searching around online and didn't find anything too illuminating out there
13:44dysfunjustin_smith: brilliant, i used a dynamic require and it works great. thanks!
13:44mikerodbeyond transients outperforming their persistent counterparts - but I wanted to also try again Java mutation
13:44mikerodJava-style*
13:47tbaldridgemikerod: dnolen has done some tests showing that transients outperform arrays on JS platforms, but no I haven't seen similar benchmarks on the JVM
13:48tbaldridgeperhaps that's just because collections are much more tunable on the JVM.
13:48dnolentbaldridge: well JS arrays are really analagous ArrayList not fixed dimension arrays
13:49dnolenso it's not surprising that transients wins, they don't have to resize as much
13:50mikeroddnolen: I have some experiments against Java primitive arrays too
13:50tbaldridgeright, but on the JVM "faster" would probably depend on your needs and what JVM collections you used
13:50mikerodI still keep "winning" with transients
13:50mikerodseems a bit impossible to me
13:50mikerodso I figure I have something wrong still
13:51mikerodI've also tried starting the ArrayList at the correct, final size. speeds it up slightly, but transient still wins
13:51mikerodtbaldridge: https://www.refheap.com/102094
13:51mikerodI think I'm keeping the pattern of access consistent here
13:55tbaldridgesome things are different however. The latter one is doing boxed math on the i value
14:28Bruce_WayneI am having trouble implementing re-com in one of my re-frame projects. Does anyone have re-com working?
14:34Bruce_Waynelooking to integrate this library:
14:34Bruce_Waynehttps://github.com/Day8/re-com
14:35dnolenBruce_Wayne: question more likely to be answered in #clojurescript
14:35Bruce_Waynethank you!
15:06whodidthisemacs prelude seems cool but does anyone know where to start if im still not getting pairing ) added when typing (, my modes are(?) Clojure Projectile Pre
15:07justin_smithwhodidthis: paredit is the mode that does that, also things like prelude are best to ditch as early as you can
15:08justin_smithbecause emacs has standard ways to manage libraries and installation, and using some hacked-up preset setup makes actually managing your own install harder, not easier, in the long run
15:10pbxjustin_smith, i'm glad to hear you say that because i've had a hard time reconciling such setups with my regular but non-leet use of emacs.
15:11luxbockI started out using emacs-starter-kit, then I moved only the things I was actually using to my own setup, but now I eventually switched over to using Spacemacs, which is even more monolithic than Prelude is
15:11stuartsierraMost pre-built Emacs set-ups I've seen give you too many new things to learn at once.
15:11luxbockand I'm a pretty big fan of it
15:11brainproxyjustin_smith: I have had nothing but success with prelude over several years and zero friction working with the standard mechanisms for libs and installations
15:11luxbockstuff breaks sometimes when I upgrade to the newest develop branch, but overall I really like having actively thought out and developed power user UI
15:11tbaldridgeemacs-starter-kit was rather recently removed. It's now just a list of packages with instructions on how to do it yourself. Big fan of that now
15:11brainproxyprelude, ultra highly recommended in my book, but i realize opinions vary on this subject
15:12stuartsierratbaldridge: glad to hear it
15:12tbaldridgeThey did a good job of walking through what each package does, and why you may or may not need it.
15:13brainproxybtw, I merge my fork with prelude's master branch almost every day (i.e. if there are changes) and in the several years I've been using it, only twice has that resulted in a problem requiring me to git reset
15:13brainproxywhich is a testament to bbatsov's care in making sure that prelude is rock-solid
15:13luxbockthe difference between now and when I was using the starter-kit before is that now that I've mostly wrapped my head around Emacs and can code in elisp then I can usually figure out pretty fast what broke and how when I upgrade
15:15brainproxyalso, check out smartparens, an alternative to paredit, actively maintained
15:15whodidthismaybe ill do starter-kit instead, seems like a good idea
15:16brainproxywhodidthis: going back to your original question, it may be that smartparents isn't enabled
15:16brainproxywhich is what prelude favors over paredit
15:17brainproxydid you copy the prelude-modules.el file from prelude/sample into ~/.emacs.d and uncomment the line for 'prelude-clojure?
15:25whodidthissounds pretty crucial actually heh, thanks
15:25brainproxysure thing
15:25whodidthisill try prelude again after testing this starter-kit
15:25brainproxysure
15:35justin_smithone of the complexities introduced by prelude is instead of emacs help, you now need prelude help
15:37brainproxycould be; I first started with it and Emacs in late 2011, when prelude was just getting its start as well; the newbie experience w/ prelude in 2015 may be different than mine, i will admit that :-)
15:37brainproxyI mainly remember spending time with plain old emacs help and fumbling around looking at prelude source ot understand what was giong on
15:37brainproxy*to
15:45sdegutisi too do not use prelude
15:46sdegutisi tried to make that rhyme but i didnt have the time
15:51brainproxyi guess my "bigger picture" view would be that a framework or starter kit that tends to hinder one's understanding and personal development of the Emacs environment is ultimately unhelpful; that hasn't been my experience with prelude, but it could affect others that way, i guess; i haven't worked with other kits, so can't really comment on them
15:52sdegutisbbl deadline
15:54brainproxya general recommendation would be to study the source of one's kit of choice and understand what it's doing for you; then, move away from it or morph it into an environment that truly serves your needs
16:30mikerodis there any sane way to search through google groups along with sort topics by time etc? I search for these topics online and don't get much help. I feel I'm always struggling to try and use google groups to look through the clj stuff and find what I want.
16:30mikerodam I just crazy?
16:31hiredmannope, google groups kind of suck
16:43aaelonyhiredman: agree
16:47mikerodhiredman: good to know
16:59mikerodhttp://dev.clojure.org/jira/browse/CLJ-1224 was bumped from major to critical recently
16:59mikerodI was hoping that also meant, bumped to 1.7 release instead :P
16:59mikerodbut I think I'm too hopefully
17:00mikerodhowever, critical does sound like a "big deal"
17:03xemdetiadoes jira have blocker like bugzilla
17:03xemdetiaor does critical already mean escalated to the mooooon
17:12fredfeWill slamhound remove unused (:require)'d items?
17:15mikerodfredfe: I doubt it
17:15mikerodthat's a hard problem too
17:15mikerodunused requires sounds very difficult to determine to me
17:15mikerodwhich does bother me about Clojure semantics with loading
17:15fredfeFunny, I'd think discovering missing items would be a bigger accomplishment lol
17:15mikerod:require can cause a namespace to be loaded and compiled for the first time. This processing can have arbitrary environmental side-effects
17:16mikerod1) define global vars 2) define protocols 3) extend protocols to types 4) create new Classes dynamically etc
17:17arohnermikerod: 5) run arbitrary clojure expressions at top-level
17:17mikerodSo my point is, how do you know what an "unused" require is? If it was transitively already loaded by another namespace, that may be ok, but then you're relying on implicit dependencies of your own dependencies, which is a bad practice.
17:18mikerodarohner: yeah, I was enumerating common ones. yes, it can certainly just do anything in the world of side effects.
17:18mikerodthis makes :require management tough from my experience
17:18fredfeMakes sense
17:18mikerodin larger libraries
17:18mikerodI often review people's code and see that they do not specify :require's that they should
17:19mikerodbecause it just happens to transitively be compiled for them
17:19hiredman:(
17:19hiredmanpeople are terrible
17:19mikerodWhich is unreliable because it can change out from underneath and break your stuff. Typical transitive dependency issues like from Maven.
17:19arohnermikerod: I have a habit of only using aliased namespaces, to prevent that
17:20mikerodarohner: yes, I like aliasing a LOT
17:20arohner(:require [foo.bar :as bar]), then only ever use bar/
17:20mikerodI get scared when people use fully-qualified symbols - which obviously should be rare
17:20mikerodbut also, if you depend on some protocol extensions from another namespace. that can get messy.
17:21mikerodI'm not saying all of this is "best practice" or anything though. I just see it come up often enough.
17:21mikerodor you make some defrecords somewhere else
17:21mikerodthen people do an :import [my.other.ns RecType]
17:21mikerodbut they don't do a :require on [my.other.ns]
17:21jarjar_primehello :)
17:22mikerodhello world!
17:22jarjar_primeis there a way to set lein deploy to use uberjar instead of the smaller one?
17:24hiredmanyou don't want that
17:25jarjar_primehiredman: I'm using that to drop into artifactory (maven) and then pull that into a dockerfile
17:29fredfeHas anyone used Jenkins with clojure? Is this how it works: Job #1 Pull project from remote git and run tests (lein test--how to capture test results?) ---> Job #2 Run `lein ring uberjar` and Publish over SSH. But what is used to keep some jar versions in case I need to perform an arbitrary number of rollbacks?
17:31hiredmanfredfe: jenkins can archive builds
17:31hiredmanfredfe: at work we just have jenkins capture the stdout of test runs and of course the pass/fail of the lein test run
17:32hiredmanwe publish built artifacts to s3
17:32hiredmanthe path on s3 as the version, so we have builds are archived on jenkins, but also on s3
18:11andyffredfe: mikerod: Eastwood linter can determine when :use or :require'd namespace is not used within a namespace, modulo some bugs where it might not report correctly.
18:11andyflein eastwood "{:add-linters [:unused-namespaces]}" https://github.com/jonase/eastwood#unused-namespaces
18:14mikerodandyf: how can it know that you aren't relying on the :require for load-compile side-effects?
18:14mikerodI know that eastwood is powerful in terms of detecting symbol references
18:14mikerodgiven that (I believe) it uses tools.analyzer to get the AST "big picture"
18:16andyfmikerod: I'm not sure what kind of examples you have in mind, but it does some magic, and not other magic :)
18:16andyfbasically if you :require or :use a namespace, but do not reference any Vars def'd in that namespace, you get a warning that the namespace is unused.
18:16andyfIt can be fooled, I am sure.
18:18mikerodandyf: having a :require to get the side effect of extend-protocol, extend-type, extend, etc
18:18mikerodthat's the most obvious one
18:18mikerodI'm guessing that is bad practice, but it has came up quite a bit from what I've seen.
18:19mikerodAnd as long as it can detect references to deftype'ed classes, that would eliminate my biggest other concern.
18:20mikerodBut don't get me wrong, I think eastwood is a great project. I was just more ranting over how :require can be tied to side-effects and makes it tricky.
18:21mikerodI see a lot of people coming from Java that think of it as like :import - but it is a lot different to that. It potentially does a lot of things, import is just sugar
18:24arohnercrazy idea of the day, I don't suppose it's possible to pass data from one nrepl to another?
18:25andyfClojure is surprisingly mutable in terms of definitions of things and loading code, and I agree that makes some things tricky.
18:25mikerodarohner: if it is in a "pure" data form you should be able to copy/paste?
18:25arohnermikerod: yeah, but I'm thinking of a lot of data
18:25mikerodandyf: yes, that is the part I'm not a huge fan of... Perhaps it is inevitable though.
18:25mikerodarohner: pr it to a file
18:25mikerodread it from the file from the other process
18:26andyfIf you treat Eastwood as "sometimes finds bugs I didn't find using other methods, but sometimes doesn't, and sometimes gives false warnings", i.e. like every other lint tool I've seen, then it might help you.
18:26mikerodedn, if you don't trust it.
18:26mikerodandyf: I think that is a good way to put it. And I think eastwood can reveal a ton of things that are very helpful.
18:27mikerodOn the topic of mutable environmental stuff, it looked like https://github.com/mikera/kiss
18:27mikerodTried to address this with "Immutable environments " I was very interested to see where that was going
18:28mikerod"immutable all the things"
18:31andyfmikerod: You can ask mikera to see if anyone has enhanced it since his proposal, but I think the status is something like "you can patch your own local copies of Clojure all you like, subject to the license". Core team probably doesn't consider it anywhere near high priority for including in the standard distribution.
18:35Drickhttp://i.imgur.com/cbOGiI8.jpg
18:39m1dnight_Is there any way to make this fail: (if-let [{a :a} {:b 1}] (println "foo") (println "bar"))
18:39m1dnight_Id hate to write an if test and only destructure in a nested let
18:39m1dnight_(in the acutal use case {:b 1} would be a call to a function)
18:40m1dnight_oh no nvm i was confused for a sec, carry on
18:48mikerodandyf: yes, I figured. I was just intrigued by the concept.
18:54reilly3000anybody know of updates to arcadia since clojure/west?
19:00Drick{`}
19:36jjttjji have a list of heavily nested maps containing things of many types. im trying to end up with a human readable list of every type that appears in the thing. I've been trying to use postwalk to just amass keep conjing an atom but think i might be on the wrong track... is there a way to only deal with leaf nodes?
19:39hiredman,(doc tree-seq)
19:40clojurebot"([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree."
19:40jjttjjhiredman: perfect, thanks!
20:10crockethttp://dpaste.com/3KYMW8W
20:11crocketHow do I consolidate "else2" and "else1" on http://dpaste.com/3KYMW8W ?
20:12crocketI want "else1" to be evaluated and returned if the innermost if-let form's binding evaluates to false.
20:12crocketDoes anyone have any idea?
20:13justin_smith(let [a "3" b "4"] (if (and a b) "then" "else1")
20:13justin_smithif "4" should not be evaluated if "3" was nil, then that can be handled also
20:14justin_smith(let [a "3" b (when a "4")] (if b "then" "else1")
20:14justin_smithif a is nil, b will be nil, guaranteed
20:14crocketjustin_smith, People are not going to write that by hand.
20:15justin_smithI write code like that by hand
20:15crocketouch
20:15justin_smithyou can use cond
20:15crocketThere is no cond-let.
20:16justin_smithsure, the let thing is a convenience, and it's not available for multiple bindings in any useful way
20:16crocketI'm looking for something like (if-let [[result1 result2] (map-all not-nil? ["1" nil])] (+ result1 result2))
20:17justin_smithdoesn't work though
20:17justin_smithit isn't there
20:17crocketWhat isn't?
20:17justin_smiththat version of if-let does not do what you want
20:17justin_smith*that usage
20:17justin_smithdestructuring + if-let = bugs
20:17amalloywelllll
20:17crocketThat's just a wtf.
20:18justin_smith,(if-let [[a b] [nil nil]] "OK")
20:18clojurebot"OK"
20:18justin_smithcrocket: that's just how it works
20:18amalloyit's a bit more nuanced than that, as i'm sure justin_smith knows. you can destructure with if-let as long as you know what is going on
20:18crocket,(if-let [[a b] nil] "ok" "no")
20:18clojurebot"no"
20:18justin_smithamalloy: right, but what I am saying is that the semantics he wants do not exist in the core language
20:19amalloyjustin_smith: i'm just taking issue with "destructuring + if-let = bugs"
20:19crocketjustin_smith, ^^
20:19justin_smithsure, yeah, that was overstating it
20:19amalloyeverything else you're saying i've only glanced at but is probably spot-on
20:19crocket,(if-let [[a b] nil] "ok" "no")
20:19clojurebot"no"
20:19justin_smithyes, I saw that the first time
20:19justin_smithbut that doesn't do what you want
20:20crocketA hypothetical function map-all should return nil if any element evaluates to nil.
20:20justin_smith,(if-let [[a b] ()] "OK")
20:20clojurebot"OK"
20:20justin_smithso even if you remove nil, it still doesn't do what you want
20:20justin_smithOK
20:22crocket(if-let [[a b] (reduce (fn [vec el] blahblah....) (map identity ["1" nil]))] "ok" "no")
20:22crocketOk, this is becoming complex...
20:22crocketI need to write a macro.
20:22justin_smithcrocket: to me that is much more complex than using when / and
20:24crocketWithout (when-let), you have to evaluate something again and bind it to a local binding.
20:24crocketThus, it leads to double evaluation.
20:24justin_smithcrocket: not in the version I proposed
20:24crocketjustin_smith, Show me your code
20:24justin_smith(let [a (f) b (and a (g))] (if b (h))
20:24justin_smithno double eval
20:25crocketjustin_smith, What if you have to do that for 7 bindings?
20:25justin_smithand (g) is not invoked if (f) was nil
20:25crocketWhat if you have to do that for 7-8 bindings repeatedly?
20:25justin_smithcrocket: then a macro that checks the prior at each step
20:25amalloycrocket: if you need to bind 7 separate things to distinct local variables your function is probably a bit lacking in purpose anyway
20:26crocketamalloy, 'probably' is not enough.
20:26amalloycrocket: the language provides you with the tools to do whatever wacky things you want. there's no "not enough" you can say about the core language, unless it makes something important impossible
20:27crocketI meant 'probably' didn't convince me.
20:27justin_smith,(let [vaues [a b nil]] (if-not (some nil? values) "OK")) ; something like this?
20:27clojurebot#error {\n :cause "Unable to resolve symbol: a in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: a in this context"\n ...
20:27justin_smith,(let [vaues [:a :b nil]] (if-not (some nil? values) "OK")) ; something like this, I meant
20:27clojurebot#error {\n :cause "Unable to resolve symbol: values in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: values in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: values in t...
20:28justin_smith,(let [values [:a :b nil]] (if-not (some nil? values) "OK")) ; should have tested it first
20:28clojurebotnil
20:30crocket,(if-let [will-you-dance-with-me nil] "ok" nil)
20:30clojurebotnil
20:30crocket,(doc if-not)
20:30clojurebot"([test then] [test then else]); Evaluates test. If logical false, evaluates and returns then expr, otherwise else expr, if supplied, else nil."
20:31crocketjustin_smith, That ends up evaluating every binding.
20:31crocketI wonder if a lazy sequence could be used for preventing evaluation.
20:32justin_smithas long as you watch out for chunking
20:32crocketouch
20:32crocketchunks of 32 items
20:32justin_smithbut, eg lists are not chunked
20:32justin_smithso you could use a list of functions
20:32justin_smithbut a reduce might make more sense unless you have another reason to want laziness
20:33justin_smithwith a reduced case if any return nil
20:34justin_smith(reduce (fn [results f] (if-let [r (f)] (conj results r) (reduced nil))) [] [f g h ...])
20:34crocketjustin_smith, That's very hard to read.
20:34crocketCan you use dpaste.com ?
20:34justin_smithone moment
20:35justin_smithhttps://www.refheap.com/102103
20:37crocketI never knew about reduced.
20:37justin_smithit makes reduce at least twice as useful I think
20:38crocketDoes reduced terminate reduce right away?
20:38justin_smithyes
20:38crocketOr, does reduce consume a sequence until the end?
20:38justin_smith,(reduce (fn [a n] (if (> n 10) a (+ n a)) 0 (range))
20:38clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
20:39crocket,(doc range)
20:39clojurebot"([] [end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0, step to 1, and end to infinity. When step is equal to 0, returns an infinite sequence of start. When start is equal to end, returns empty list."
20:40crocket,(take 10 (range))
20:40clojurebot(0 1 2 3 4 ...)
20:40justin_smith,(reduce (fn [a n] (if (> n 10) (reduced a) (+ n a))) 0 (range))
20:40clojurebot55
20:40justin_smithrange returns an indefinite sequence - so (range) won't return for a while if eagerly consumed
20:40crocketHow does clojure catch that?
20:40justin_smithcatch which?
20:41crocketHow does clojure catch an infinite evaluation?
20:41justin_smithit generally just lets it happen, but clojurebot has print-level and print-length set up to avoid indefinite printing, which with something lazy, prevents indefinite forcing
20:42justin_smith,(reduce + (range))
20:42clojureboteval service is offline
20:42justin_smiththat's because it timed out, of course
20:43crocketI wish clojure caught infinite loops.
21:06weiinteresting puzzle for you all: I want to walk a nested vector and build up an array of indices. e.g. (indices [1 [1 [1 1]]]) => [[0] [1 0] [1 1 0] [1 1 1]]
21:07gfredericks,(defn indices [v] (map-indexed (fn [i x] (if (vector? x) (map #(cons i (indices %)) x) (list i))) v))
21:07clojurebot#'sandbox/indices
21:07gfredericks,(indices [1 [1 [1 1]]])
21:07clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
21:08gfredericks,(defn indices [v] (map-indexed (fn [i x] (if (vector? x) (map #(cons i %) (indices x)) (list i))) v))
21:08clojurebot#'sandbox/indices
21:08gfredericks,(indices [1 [1 [1 1]]])
21:08clojurebot((0) ((1 0) (1 (1 0) (1 1))))
21:08gfredericks,(defn indices [v] (apply concat (map-indexed (fn [i x] (if (vector? x) (map #(cons i %) (indices x)) (list i))) v)))
21:08clojurebot#'sandbox/indices
21:08gfredericks,(indices [1 [1 [1 1]]])
21:08clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
21:08gfrederickspoopsiedoodle
21:09gfredericks,(defn indices [v] (apply concat (map-indexed (fn [i x] (if (vector? x) (map #(cons i %) (indices x)) [[i]])) v)))
21:09clojurebot#'sandbox/indices
21:09gfrederickspoopsiedoodle
21:09gfrederickswhoops false poopsiedoodle, meant to scrollback farther
21:09gfredericks,(indices [1 [1 [1 1]]])
21:09clojurebot([0] (1 0) (1 1 0) (1 1 1))
21:10gfredericksphew okay there we go
21:10gfrederickswei: ^
21:12weinice!!
21:13wei(inc gfredericks)
21:13lazybot⇒ 139
21:14gfrederickshoo ray a prime
21:16weiwish there was a mapv-indexed
21:31crockethttp://dpaste.com/36F19FE generates an error.
21:31crocketHow can I fix it?
21:50crocketHow do I make a macro call itself safely?
21:57crocketI created the first working prototype of if-let-all. http://dpaste.com/0S2VYM5
21:57crocketYay
22:00crocketCan anyone evaluate if-let-all?
22:02gfrederickscrocket: I found a bug
22:02crocketWhat is it?
22:02gfredericks(if-let-all [x (seq ())] :true-case :false-case)
22:02crocketWhy is it a bug?
22:02gfredericks,(if-let [x (seq ())] :true-case :false-case)
22:03clojurebot:false-case
22:03crocketoops
22:03gfredericksthis is a common macro pitfall
22:03gfredericksyou're preforming your logic on the forms at compile-time
22:04gfredericks(coll-or-nil only runs once when you're compiling the macro call)
22:07crockethmm...
22:07crocketI think coll-or-nil should evaluate...
22:08crocketgfredericks, How about http://dpaste.com/3B45AFB ?
22:08crocket(eval f) fixes the bug.
22:08gfredericksand that's the next pitfall :)
22:08crocketWhat is it?
22:08gfredericksusing eval to fix the first pitfall
22:08gfrederickshere's the next bug
22:09gfredericks(let [a ()] (if-let-all [x (seq a)] :true-case :false-case))
22:09crocket,(let [a ()] (if-let [x (seq a)] :true-case :false-case))
22:09clojurebot:false-case
22:10hasketWhat are people's opinion on haskell vs clojure for web dev
22:10hasket(backend)
22:10crocketgfredericks, Do you know a solution?
22:10crockethasket, Why don't you try them?
22:11crocketFor web development, both languages are far superior to ruby, java, and python.
22:11gfrederickscrocket: you need to be doing the logic at runtime, not compile time; to do that you need to emit code that does the logic
22:11gfrederickscrocket: I'd play with macroexpand-1
22:11gfredericksthat might give more insight into where things aren't working
22:12hasketI know Haskell quite well. I'm just curious as to what clojure has to offer (I know it's an amazing language and I've played around with it a bit, but not extensively).
22:12crocketmacroexpand-1 doesn't help me with (let [a ()] (if-let-all [x (seq a)] :true-case :false-case))
22:12crockethasket, One word, ClojureScript.
22:12crocketClojure & ClojureScript
22:12gfrederickscrocket: you can macroexpand just the if-let-all part
22:13hasketcrocket, yeah I've tried GHCJS and it's a pain in the butt to install and keep track of dependencies
22:13hasketlein seems to work much better than cabal
22:14hasketBut I'm in love with Haskell's type system is the issue. Does clojure provide any kind of type safety? Or some assurance of safety?
22:14crockethasket, You can use PureScript.
22:14crockethasket, clojure has different ways of ensuring interface integrity than haskell....
22:15skeuomorfhasket: https://github.com/clojure/core.typed
22:15crocketThat being said, haskell is better at checking compile time errors.
22:16hasketcrocket, yeah that's what it seems like, but I'm fascinated by the language also. I love functional programming. One of my favorite things about haskell is that you can write out the types, then if you don't know the type of something should be in your code, you can leave a hole and haskell will figure out relevant types in scope and tell you what type the hole has. What drew you to clojure? I love the talk "simple made easy" which brought me
22:16hasket here :)
22:17crockethasket, It's simple.
22:17crocketIt's concise.
22:18hasketCool, I'm gonna learn it. I love learning new languages anyways so it's not even necessarily about trying to do anything with it rather than the beauty of the language itself (at least for me). Clojure looks like an elegant language
22:19hasketAnd compiling with ghc and cabal in haskell can be a pain in the butt
22:22crocketgfredericks, How do you make if-let-all work?
22:22crocketIt seems I can't evaluate values in if-let-all.
22:23crocketBecause values are defined outside the scope.
22:23gfrederickscrocket: your macro shouldn't be evaluating them
22:23gfredericksmacros are about rewriting the code
22:23crocketgfredericks, Does it mean I have to duplicate the else clause as many times as bindings?
22:23gfredericksno
22:23crocketThe use of (if-let) leads to multiple instances of the same else clause.
22:24gfredericksbut you have coll-or-nil
22:24gfredericksso you can write this with only one if-let
22:24crocket????
22:25crocketgfredericks, I thought about nesting if-let.
22:25crocketIf you nest if-let forms, you'll get multiple else clauses.
22:26gfredericks(if-let [[a b c] (coll-or-nill [x y z])] true-case false-case)
22:26gfredericks^ you want to write it that way, right?
22:26crocketYes, I did
22:26gfredericksso your macro needs to emit code that looks like that
22:26gfredericksthe macro does *not* need to call coll-or-nil itself
22:26crocketok
22:27gfredericksin your original code it does, because of the unquoting
22:27gfredericks~(coll-or-nil values)
22:27clojurebotI don't understand.
22:27crocketgood
22:27crocketgfredericks, Does it mean I have to expose coll-or-nil?
22:27gfredericksyou mean make it not-private?
22:27crocketYes
22:28crocketI wanted to make it private.
22:28crocketwith defn-
22:28gfredericksyou cannot do that easily
22:28crocketI should probably inline coll-or-nil in if-let-all.
22:29gfredericksbtw if you're going to be using this for serious stuff you might want to think about the fact that your current approach doesn't short-circuit -- it will evaluate all of the "values" no matter which ones are nil
22:29gfredericksyou also can't use previous values in the later expressions
22:33gfrederickscrocket: http://www.infoq.com/presentations/macros-clojure-west-2013
22:37crocketgfredericks, Does anyone have a better version of if-let-all?
22:39gfredericksprismatic/plumbing and flatland/useful are a couple places to check
22:39gfredericksI don't often find myself wanting it so I'm not sure
22:42gfredericksif I had to write it I'd probably use a function or a sentinel to avoid the repeated else clause problem
22:42tstoutWhat are the scope rules of a namespace? For example, can a single file define multiple namespaces? Can multiple files contribute to the same namespace?
22:42gfredericks(and so still use nested if-lets)
22:42gfrederickststout: there aren't rules about that, only conventions
22:42gfrederickststout: one-to-one is the convention, and there are probably a lot of tools that assume it
23:03crocketBy the way, when-let doesn't have else clause problem.
23:07gfrederickswhen-let doesn't have an else at all
23:08figoeSomething weird
23:08figoeuser=> (into {} (list (vector :a 3))) => {:a 3}
23:08figoeuser=> (into {} (list (list :a 3))) => ClassCastException clojure.lang.Keyword cannot be cast to java.util.Map$Entry clojure.lang.ATransientMap.conj (ATransientMap.java:44)
23:09figoeAny ideas? :)
23:09gfredericksfigoe: it's a little weird but that's how it works
23:10gfrederickspairs for maps have to be vectors
23:10figoeYes, just got bitten by ... heh
23:10figoeGuess I gotta do a walk to convert the nested structure to vector or some way
23:11crocketgfredericks, When do you use if you want something like if-let-all?
23:14crocketWhen -> What
23:16gfrederickscrocket: I think I rarely need more than two clauses and so I just tolerate a bit of repetition
23:16mbufin the "Language of the System" talk, it was mentioned that Clojure has the notion of system namespace. Are there any examples to illustrate this?
23:17andyftstout: I'm a little late in answering, but Clojure's require and use determine the source file name to read based upon the namespace name, and check that the namespace has been defined after loading the file. You could define additional namespaces in that same file with other namespace names, but you could not require or use those namespaces successfully from that file.
23:17gfredericksmbuf: I can't remember him saying that nor can guess what it means; any further context?
23:17mbufgfredericks, like the use of namespaces in datomic with zookeeper and riak
23:18gfredericksmbuf: still nothing, sorry :/
23:18crocketI guess people haven't needed to use a lot of bindings in if-let.
23:18gfrederickscrocket: I'll write one up in a minute
23:19andyfcrocket: A multiple-binding if-let has been asked about multiple times over the last few years on the Clojure Google group. Different people have written different variants of it as macros.
23:22ToBeReplacedseems like too much control-flow to put into the language itself... i think i like that you need to define your own so that you have to decide the semantics you want
23:23ToBeReplacedand the "if all of these bindings are non-nil then do this else that" version is very easy to write and a good exercise if you haven't written a binding macro before
23:23mbufgfredericks, https://www.youtube.com/watch?v=ROor6_NGIWU 36:00 - 37:30
23:26gfredericksmbuf: I'm can't listen to noise atm, sorry
23:27mbufgfredericks, okay
23:27cfleminggfredericks: I'm going to tell Rich you said that
23:28gfrederickscfleming: no no! don't tell him! oh god
23:28gfredericksI didn't mean that kind of noise
23:28gfredericksoh no
23:28cflemingThat was an even better reaction than I was hoping for
23:29gfredericksnow he's never going to accept my patch for CLJ-1237
23:30cflemingThat does look like it would have been difficult to debug
23:30gfredericksand then it happened to my teammate a year later!
23:41gfrederickscrocket: give this a try https://www.refheap.com/102107
23:42crocketJesus
23:45crocketgfredericks, Is it better to call recur instead of self in self?
23:45gfrederickscrocket: it's impossible
23:45gfredericksit's not a tail call
23:45crocketimpossible?
23:46gfredericksif you try it you'll get a compile error
23:46crocketI don't know what self does.
23:46gfredericksthat's just a name I gave the function
23:47gfredericksor you mean what that function does
23:47gfredericksit sets up (if-let [a x] (if-let [b y] (if-let [c z] [a b c])))
23:47gfrederickswhich gives you short-circuiting and visibility of previous results
23:48crocketWhat is short-circuiting?
23:49gfredericksif x is falsy it won't evaluate y or z
23:53crocketgfredericks, (if-let-all [a 2 b 2] "ok" no") is translated to something like (let [temp [a b]] (if temp (let [[a b] temp] "ok") "no"))
23:54gfrederickscrocket: that approach doesn't give you short-circuiting
23:54crocketWhut
23:54crocketgfredericks, I used https://www.refheap.com/102107
23:58gfrederickswhen I expand it I get (if-let [[a b] (if-let [a 2] (if-let [b 2] [a b]))] "ok" "no")
23:58gfrederickswhich is short-circuiting
23:59gfredericksyou can try (if-let-all [a (do (println "a") nil) b (do (println "b") 2)] "ok" "no") to test out short-circuiting properties