#clojure logs

2015-02-26

00:07mercwithamouthdoes anyone here prefer luminus to compojure? is luminus an alright choice or does it completely take over?
00:08ddellacostamercwithamouth: I think that it's hard to compare them--luminus uses compojure as far as I know, just includes a lot more and acts as more of a comprehensive framework
00:09ddellacostamercwithamouth: and I think you can see that it is opinionated about certain choices, but I can't speak to how hard it is to override certain things in luminus, sorry...maybe someone else can
00:31mercwithamouthddellacosta: fair enough. i think i'm fine with just compojure. though i'm sure luminus isn't as overbearing as rails
00:31l1x' (for [a [0 1] b (range 10)] [a b])
00:31ddellacostamercwithamouth: yeah, having been a Rails dev for a while I think it's probably safe to say that--luminus is much more a set of composed libs vs. how monolithic Rails seems
00:35mercwithamouthgoos to know
00:38niac(walk (fn [[k v]] [k (* 10 v)]) identity {:a 1 :b 2 :c 3})
00:39niaccan it rewrite #()
00:39niacinstead of fn
00:43ddellacostaniac: here's one way:
00:43ddellacosta&(clojure.walk/walk #(vector (key %) (* 10 (val %))) identity {:a 1 :b 2 :c 3})
00:43lazybot⇒ {:c 30, :b 20, :a 10}
00:43ddellacostanot sure that's much nicer
00:44ddellacostaor,
00:44ddellacosta&(clojure.walk/walk #(let [[k v] %] [k (* 10 v)]) identity {:a 1 :b 2 :c 3})
00:44lazybot⇒ {:c 30, :b 20, :a 10}
00:45ddellacostabut considering the fn version is less verbose than these, I wouldn't bother
00:45l1x&(for [a [0 1] b (range 4)] [a b])
00:45lazybot⇒ ([0 0] [0 1] [0 2] [0 3] [1 0] [1 1] [1 2] [1 3])
00:47niacddellacosta: maybe the fn is the best way
00:48ddellacostaniac: I mean, it all depends on context. What you're trying is obviously a toy example. Probably if it was a real implementation of something, you'd have that second arg be a named fn somewhere
00:50niacddellacosta: thanks . i just try some code example on the web.
01:27michaler`going to implement users/roles/permissions system
01:28michaler`i wonder if there is anything out there which i can use instead of rolling my own
02:41bashedIf I have a number of paths as vectors like [Home, Nav, Menu, Search] and [Home, Nav, Sign out], how do I merge them into a single tree. My current approach involves using 'assoc-in', since assoc-in creates hash-maps if any levels don't exist.
02:42bashedI want to store specific info for each of the vertices in the tree as well. Including their name, path, and additional information on them.
02:45TEttingerthat's a good question, bashed, but I don't feel qualified to answer
02:45TEttingerit might be a clojure.zip thing
02:45eglimichaler`: have you looked at friend?
02:46TEttingerhttps://www.refheap.com/97807 generating lots of old-testament-style names, I hilariously generate Eris and Vol right next to each other (goddess of discord and a god in a D&D setting)
03:23michaler`egli: hi
03:24michaler`egli: i've used friend a while back but i don't think it provides a full roles/permissions solution
03:27eglimichaler`: what is a full roles/permissions solution? friend has roles (https://github.com/cemerick/friend#authorization) and even provides hierarchical roles (https://github.com/cemerick/friend#hierarchical-roles-ht-derive-isa-et-al)
03:29sveriI dropped friend in favour of buddy
03:30eglisveri: sure, buddy looks interesting
03:32sveriI don't want to say it is bad or something, however, I had one bad experience with it and the lack of documentation of proper integration was hard to when I wanted to use it
03:35michaler`egli: it provides some basic infrastructure maybe.. but i'm looking for a more full solution
03:36sverimichaler`: when having fun in the java world I always used shiro and if there wasn't buddy I would have thought about wrapping shiro in some clojure lib
03:37sverimichaler`: maybe this is something for you?
03:41michaler`sveri: i'm actually using buddy for this project too. also found some mention of wrapping shiro in clojure while searching google and the author wasn't sure whether the effort was indeed worth while.
03:42michaler`sveri: also it sounded like they invested a lot of time into that. I'm hoping to have some basic simple system done today :)
04:12EremoxDoes clojure have separate namespaces for functions and vars like common lisp?
04:12justin_smithno
04:13hiredmanno, and vars in clojure are a kind of reference type, where in common lisp "var" is just short for variable
04:14hiredman(which can be confusing when people trying to ask questions about "vars")
04:16hiredman(namespaces are also a thing in clojure, sort of analogous to packages in common lisp)
04:17TEttinger(inc hiredman)
04:17lazybot⇒ 72
04:19EremoxOK and functions are just like values in that vars reference anonymous functions? Which gives functions names right?
04:20justin_smithright, you can use (def foo (fn ...)) instead of (defn foo ...) except for the fact that defn adds some helpful metadata too
04:20justin_smithotherwise they are equivalent
04:20hiredmancorrect
04:20hiredmanbut vars are not the only way names are bound to values
04:20EremoxOK thanks.
04:21hiredmanlocals also bind names to values
04:21hiredmanlocals are function arguments or let bound names
04:22ordnungswidrig`fn` also can take a symbol for the name but I never understood it's purpose. defn macroexpands to fn without that.
04:22hiredmanvars in clojure are the mutable cells that the top level bindings create with def create (def always defines a name at the top level, not like in scheme), locals are immutable
04:22justin_smithordnungswidrig: the purpose is twofold: self calls that are not in tail position, and making stack traces readable
04:23ordnungswidrigjustin_smith: I see. But why doesn't defn use the name argument to fn?
04:24ordnungswidrigDoes the compiler do some extra work for the stacktraces if it finds a function in a var?
04:24justin_smithordnungswidrig: because it doesn't need that for either of those reasons (the var / metadata suffice)
04:24justin_smithyeah, that's why it shows function names in stacktraces
04:25ordnungswidrig(def foo (fn bar [] (throw (Exception. "bogus")))) (foo)
04:26ordnungswidrigthat shows "bar" in the stacktrace. evil :-)
04:27TEttingerI've taken to using variables named bogus and intentionally filled with impossible data when I need a value to indicate an invalid, non-nullable C# struct
04:27TEttingerI like nil better :(
04:36EremoxDoes anyone have any good explanation of currying or a good article for it? I think I have been mixing closures and currying..
04:39tomjack,(let [plus (fn [x] (fn [y] (+ x y)))] (map (plus 3) [4 5 6]))
04:39clojurebot(7 8 9)
04:40justin_smithor you could just use partial, but neither that nor partial are currying
04:40GlenjaminEremox: are you familiar with partial application?
04:40Glenjamincurrying is related, but i think partial is easier to grok initially
04:40justin_smith,(map (partial + 3) [4 5 6])
04:40clojurebot(7 8 9)
04:40tomjackwhat is currying if not that?
04:41EremoxYeah I think I get partial
04:41justin_smithtomjack: with currying the function returned will itself curry
04:41tomjackah, just a different perspective. I think of 'currying' as some grunt work I have to do to my code
04:41justin_smiththe point of currying is that it is implicit
04:41tomjackyou think of it as something the function does for you, I guess
04:42justin_smithand clojure doesn't have currying - we opted for allowing varargs instead
04:42tomjackas a language feature, sure
04:42justin_smithtomjack: currying and partial evaluation both have definitions, and they are not the same
04:43tomjackI don't find dictionaries very useful
04:43tomjackbut: http://en.wiktionary.org/wiki/currying
04:43EremoxIn the source of clojure there is a macro called defcurried or similarly why isn't that part clojure?
04:43tomjackthe definition there seems to describe exactly what I thought did above :)
04:43tomjacks/did/I did/
04:44justin_smithtomjack: "Currying is converting a single function of n arguments into n functions with a single argument each."
04:44justin_smithclojure's + cannot be curried, because it takes 0 or more args
04:44sverimichaler`: Well, I guess you will, I found it easy to integrate, do you need an example?
04:44tomjacksure, I considered only the 2-arity of +
04:44tomjack:)
04:45tomjackconversely, I guess, when doing the transformation in a curried language, one must introduce explicit vectors
04:46justin_smithtomjack: well, I guess you did turn + into two functions with one argument each
04:47justin_smithin other words, clojure is annoying because you have to do explicit partial application because it isn't a currying language, and ML family languages are annoying because they don't provide convenient varargs
04:47justin_smithbecause varargs and currying mix very poorly
04:48tomjackI've been planning to attempt an experiment
04:48tomjackbuild a toy language with the Clojure reader, which fully embraces ambiguity
04:49tomjacktry to write code and see which kinds of ambiguities make everything horrible
04:50tomjacke.g. (instance? (-> Nat Nat) (+ 3)) but also (instance? Nat (+ 3)) ?
04:51justin_smiththat would lead to some seriously ambiguous bugs
04:52justin_smithtransducer arities are a miniature versin of the problem
04:52tomjackthe language should have a type system expressive enough to eliminate bugs, and there should be some elaboration procedure through which a program is only accepted if the ambiguity can be resolved
04:53justin_smith(they are useful, I am glad they are there, but we lose compile time errors for a class of mistakes)
04:53tomjackor, if you type an ambiguous program at the repl, I guess we can let you choose whether to run them all, look at them and pick, or whatever
04:54tomjackbut I'm sure things will still be horrible if certain kinds of ambiguities are allowed...
04:55justin_smithtomjack: it would be a big change, right now clojure is not a "clever" compiler
04:56tomjackah, uh, yeah.. the experiment would be a separate toy language with just some cosmetic similarity to clojure
04:56justin_smithyeah, just saying you wouldn't be able to leverage what exists very much is all
04:58tomjackright, except for (some) ideas and the reader, and Clojure in the non-meta-circular implementation
04:59tomjackI conjecture that a small subset of Clojure is a good fit for the operational semantics of such a language
04:59tomjack(if you can write a small clojure.core.logic{,.nominal}, I guess :( )
05:00tomjackmicrokanren provides some hope
05:00justin_smithI've been awake for 22 hours, time for sleep
05:00tomjackditto :(
05:01justin_smithI saw an excellent horror film with sleep deprivation themes today too
05:01justin_smithbabadook
05:01justin_smithbye
05:01ordnungswidrigjustin_smith: have a great nap.
05:36tomphpHi
05:40tomphpI have a rather a couple simple interop (proxy) question which I can't find any references to
05:40tomphp1) Can you set a constructor function?
05:41tomphp2) how to you call other "methods" in the object - is proxy-super only for super or is there a this/self function?
05:41tomphpthanks ;-)
06:22mnngfltgIn my REPL: OutOfMemoryError PermGen space java.lang.ClassLoader.defineClass1
06:22mnngfltgwhat now?
06:36hyPiRionrestart repl
06:36hyPiRionand/or run java 8
06:38mnngfltghyPiRion, installing java 8 now
06:53martinklepschmnngfltg: hyPiRion or https://github.com/boot-clj/boot/wiki/JVM-Options#permgen-errors
06:54martinklepschI'm trying to get some clj-webdriver stuff to work to test some reagent app. I constantly get errors like org.openqa.selenium.StaleElementReferenceException even though I don't hold any references to any elements myself
06:56martinklepschmy test looks like this: https://gist.github.com/martinklepsch/8c80e90fbd2ec332d0c6
07:27ggherdov,(cons :a [:b])
07:27clojurebot(:a :b)
07:27agarman,(conj [:b] :a)
07:27clojurebot[:b :a]
07:27ggherdovuhm. I'd like [:a :b] instead
07:28agarman,(conj #{:b} :a)
07:28clojurebot#{:b :a}
07:28agarman,(conj '(:b) :a)
07:28clojurebot(:a :b)
07:28ggherdovsure, but conj puts the elem wherever it pleases it.
07:28ggherdovi'd like to keep the collection type -and- prepend the new elem.
07:29agarmanit puts it at the best place by the data structure
07:29agarmanprepending to a vector is **slow**
07:30agarmanit's designed for append
07:30agarmanappend is O(1) v O(n log n)
07:30agarmanfor prepend
07:31ggherdovbase of the log? is it the log32 thing?
07:31ggherdovanyway I have small vectors, I was just ranting at cons changing the type.
07:32agarmancons operates on lists, just like it does in every other lisp ever
07:32ggherdovok
07:33agarmanfar more people would bitch about that changing than having to use conj if you want to retain the collection type
07:33ggherdovI see
07:35agarmanalso, if you want to pull elements out of a vector without changing the collection type:
07:36agarman,(rest [1 2 3]) (next [1 2 3) (pop [1 2 3])
07:36clojurebot(2 3)
07:36agarman,[(rest [1 2 3]) (next [1 2 3) (pop [1 2 3])]
07:36clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>
07:36agarman,[(rest [1 2 3]) (next [1 2 3]) (pop [1 2 3])]
07:36clojurebot[(2 3) (2 3) [1 2]]
07:36ggherdovok
07:37agarman,[(first [1 2 3]) (peek [1 2 3])]
07:37clojurebot[1 3]
07:38agarmanor just use cons, first et al because your vectors are small (ergo they'll likely work just fine as lists)
07:39ggherdovsure
08:10hitekihi
08:47mnngfltgmartinklepsch, figured out how to update to sun's java 8 on nixos, now hopefully fewer permgen problem (I get them in `lein` as well as in `boot`)
08:48martinklepschmnngfltg: well, that JVM options thing should work for both :)
08:49mnngfltgmartinklepsch, ... if you're willing to allocate 100s of MB or permgen space for every leiningen process, just to be safe
11:26pepijndevosWhat is the web stack du jour?
11:27mbacwhat are some fun clojure tutorials
11:27mbacrather, exercises to work through
11:27shiranaihitopepijndevos: ring? :)
11:27mbaci have some time coming up and i want something to keep my skills sharp on between sipping margaritas on the beach
11:29sverimbac: 4clojure.com
11:29mbacwhoa, that's awesome
11:30pepijndevosshiranaihito, yea, I just need some routing and misc utilities
11:30csd_Suppose I have an effectful function, as well as a function that calls effectful function. How might I write something to compare whether the two functions are equal given similar arguments, which out executing effectful function?
11:30csd_is it just a bad idea altogether?
11:30Glenjamin(doc with-redefs)
11:30shiranaihitopepijndevos: alrighty
11:30clojurebot"([bindings & body]); binding => var-symbol temp-value-expr Temporarily redefines Vars while executing the body. The temp-value-exprs will be evaluated and each resulting value will replace in parallel the root value of its Var. After the body is executed, the root values of all the Vars will be set back to their old values. These temporary changes will be visible in all threads. Useful for mocking out functions during testing."
11:31sveripepijndevos: shameless self plug: https://github.com/sveri/closp
11:32csd_Glenjamin: so use with-redefs to rebind effectful-fn to identity, for example, and then evaluate for equality?
11:32Glenjaminyeah, i wouldn't use it heavily - but that's the simplest way to do what you describe
11:34chouserwhat do you mean, "the two functions are equal"?
11:34csd_Glenjamin: ok what if calls-effectul-fn is already defined and is the function I'm trying to test?
11:34TimMc,(with-redefs [rand (constantly 100)] (rand-int 5))
11:34clojurebot100
11:34csd_I don't think with-redefs would work in that case
11:35Glenjaminwith-redefs can only replace existing functions afaik
11:36TimMccsd_: Function A wraps function B, and you want to test that A passes its args unchanged to B and passes the return value back unchanged?
11:36subhashgosveri: That's an interesting template, thanks
11:36csd_I want to do a test like (= (effectful-fn immutable-arg mutable-arg) (call-effectful-fn immutable-arg mutable-arg))
11:36csd_so it needs to check that effectful-fn is the same function in either instance, and that the args are equal
11:37mbacthis 4clojure.com thing is so good
11:37sverisubhashgo: np, your welcome
11:37mbacit should say achievement unlocked at milestones
11:38csd_does what i'm saying make sense?
11:38TimMcDo you just want to test that B was called?
11:38puredangermbac: tell amalloy_
11:38csd_yeah, basically. i'm testing a function that has a cond in it, and i want to check that under the right condition that it calls effectful-fn with the args i'm passing to the wrapper
11:40csd_and i think the cleanest way to do that would be not to let effectful-fn execute
11:40chousercsd_: I suspect your code could be reorganized to be more testable, and might also then be more reusable and possibly easier to understand. That said, rebinding effectful-fn to capture its args and store them somewhere you can check later should work.
11:41csd_rebinding in the test code or in the non-test code?
11:42chouserin the test code
11:43hitekihi
11:43Glenjaminhttps://clojars.org/bond and https://clojars.org/q can wrap up some common patterns
11:43Glenjaminfor rebinding functions in tests
11:43TimMccsd_: (let [calls (atom [])] (with-redefs [B #(do (swap! calls conj %&) :return)] (A :foo :bar))) and then test that @calls has one vector of the right vals.
11:44chousercsd_: (let [caught (atom [])] (binding [effectful-fn (fn [& args] (swap! caught conj args))] (effectful-fn ...) (call-effectful ...) (is (= (first caught) (second caught))))) ...or some such
11:44Glenjaminthat's what https://github.com/glenjamin/q#with-stubs-fns--body does internally
11:44TimMccsd_: Or if you're using midje, (fact (A :foo :bar) => :return (provided (B :foo :bar) => :return))
11:46csd_ok but calls-effectful-fn is within the non-test code, and i would think that's where the binding would have to go
11:46TimMccsd_: This is too confusing, you should post an example.
11:49csd_So here's the non-test function. https://www.refheap.com/97822 I want to be able to test the effectful functions without having to pass and test these large state maps
11:49csd_i'm also experimenting with adding these keywords as an alternative method of testing
11:50justin_smithcsd_: my usual approach to make things testable is split the logic from the actions
11:51justin_smiththe function with the actions should be trivial, and then you test the result of the function with the logic
11:52justin_smithit's kind of like the "interpreter pattern" I think - the decision making function returns a data structure that tells the side effecting function what to do
11:52csd_and so effectively you're testing the return value of the side effecting function when you test the decision making function?
11:53justin_smithcsd_: well, you've refactored the problem, so you are testing that your logic is correct
11:53justin_smithand the side effecting function will be easier to test with no logic, and may be trivial enough to not really require testing (thinly wrapped library call)
11:54csd_how are you testing the correctness of the logic without looking, indirectly, at the return values from the sideeffecting functions?
11:54justin_smith"no logic" is of course a relative exagerration - but the goal here is to limit the intermingling of decisions and side effects, so that each are easier to test
11:54justin_smithby testing their return values of course
11:55justin_smithwhich in the actual program will "drive" the side effecting functions
11:55justin_smiththe logic half should take all the relevant args, and return a data structure, the side effecting half should take a data structure, perform an action, and return nil
11:55csd_are you aware of any code samples that might demonstrate this? i'm somewhat confused
11:56justin_smithI use it in my own projects, let me find a decomplected example
11:56TimMcThis is like the instruction decoder on a CPU.
11:57justin_smithTimMc: kind of, yeah
11:57TimMctaking a complex instruction and breaking it down into a smaller set of individual, sequenced actions to perform.
11:58chouserjustin_smith: return values may not always be the best way to communicate what should be done. An alternative is to pass in the functions to be applies, so that you can pass in either effectful or pure fns.
11:58chouserYou know, like you do to "reduce" :-)
11:59justin_smithchouser: it's true, that is also a good alternative
12:00justin_smithbut regardless, the goal is to separate "what to do" from "doing the side effects" so that they can both be more easily verified correct
12:00chouseryes
12:00chouserbecause "what to do" is usually more complicated but easier to test.
12:00csd_but when you test the has-logic-and-calls-isolated-side-effects, you still need to look at the its return value to judge correctness, and its return value is going to be a result of the side effecting functions
12:01chouser"doing the side effects" of course should be tested as well, but that usually requires more complex setups. VMs and such.
12:01justin_smithcsd_: thare's also a very small function at the top that connects the decision maker and the side effector
12:01justin_smithwhat you test about the decision making function is the data structure it returns
12:01justin_smithor in chouser's version, you pass it a verifier function instead of a side effectful one
12:02justin_smithbrb, shower and coffee
12:03csd_ultimately i think you want, when test has-logic-and-calls-isolated-side-effects, is for the side effects not to occur. but they're still there in the function. so how can they not
12:08justin_smithcsd_: it's not one function that does both of those
12:08justin_smithone function returns data representing the thing to be done
12:08justin_smitheasy to test
12:08justin_smiththe other takes data, and does an action
12:08justin_smitha third function connects them
12:09justin_smithcsd_: a good example is in ring, with a well designed ring app
12:09csd_ok conceptually i get what you're saying
12:09justin_smithall the request data is in an immutable data structure, each middleware returns a modified map representing some decision made, or some piece of data pulled in etc.
12:10justin_smiththe handler function does not do anything with side effects usually - it returns a map that tells ring how to construct a response
12:10justin_smithyou can easily test the handler by passing it a map, and then looking at the map it returns to you
12:10csd_i see
12:11justin_smithit's the infrastructure of the ring server that ties this all together, and attaches the result of rendering that map to a response to the client
12:11csd_and so the map contains the side effecting function that has to call it
12:11csd_or rather, that the interpreter calls on it
12:12justin_smithno, in this case the ring server itself does the side effects, which are about reading from clients and writing back to client sockets
12:12csd_oh i mean in general, not specifically for ring
12:13justin_smithOK, then that can be the way it is done, but there are other structurings available
12:13justin_smithand in practice the handler/app function is not perfectly side effect free
12:13TimMcAlternative to pprint that doesn't botch vars?
12:14csd_justin_smith: where can i learn more about this?
12:14stuartsierraTimMc: dunno if it handles Vars, but bbloom's ffipp might be pluggable
12:14justin_smithcsd_: hmm... you could look at how monads are used in Haskell I guess?
12:15justin_smiththere are books that cover this stuff I am sure...
12:15csd_whys that
12:15justin_smithcsd_: this is exactly what monads do, they isolate side effecting code from program logic code
12:16hiredmanhttp://dev.clojure.org/jira/browse/CLJ-1576 vote early and often
12:16justin_smithor maybe better to say they knit them together in a very specific way
12:17TimMcstuartsierra: Thanks!
12:18profilanybody who has used aleph with core.async? I am trying to connect aleph(manifold) streams to a core.async channel
12:18csd_justin_smith: ok thank you for explaining all this to me
12:21justin_smithcsd_: I think it makes a lot more sense when you try it. Start with chouser 's version of passing either a side effecting function or a verification function to the function that does the logic
12:21justin_smiththat is probably the simplest way to try this general pattern
12:23justin_smithcsd_: so, more concretely, with join-channel, you would probably pass a function representing what currently uses its return value in to the function, and you would probably also want to put some of the side effecting code from join-channel into that function you pass in (by returning a vector of data instead of one keyword)
12:23justin_smiths/returning/passing in
12:23justin_smithoops!
12:30csd_justin_smith: yeah, now i'm just thinking about where in my code i want to put the interpretter exactly
12:30crazydiamondHi. What tool may I use to effectively read large Clojure EDN file? Also, what format is better to store large piece of data? May be JSON or XML is better?
12:37justin_smithcrazydiamond: I don't know if edn is apropriate for large files. Depending on how big "large" is of course.
12:38crazydiamondjustin_smith, well, 42 megabyte of EDN
12:38justin_smithclojure.edn/read should handle that fine
12:38justin_smithbut definitely pass in a buffered reader, don't slurp a string then read-string
12:39crazydiamondgood to know
12:40crazydiamondmy file contains sequence of things, and I have function that I'm applying to each item in sequence (and tweaking the function each time)
12:42justin_smiththe most efficient way to do that general pattern may be one record per line of the file mixed with line-seq and either doseq or for
12:42justin_smithunless the input file is a given
12:51crazydiamondjustin_smith, is this example of buffered reader?
12:51crazydiamond(with-open [rdr (clojure.java.io/reader "/tmp/foo.txt")]
12:51crazydiamond (reduce conj [] (line-seq rdr)))
12:54l1xmorning
12:54l1xjustin_smith: do you have a second? i was running into this very interesting problem and i was wondering if you could shed some light
12:54clov3rHello #clojure. I have a question, trying to make a partially applied functions with java.lang.String's .contains
12:55clov3rbut (partial .contains "a") gives a runtime exception, unable to resolve symbol
12:55l1xhttps://gist.github.com/l1x/836b23fe864dd0db1259
12:56l1xi am trying to process N message streams lazily and I need to consume 1 (or few) message from each stream
12:57l1xbut obviously if you do for [stream streams] it is trying to finish to process the first stream before moves on to the second one
12:57l1xi was wondering how could i process them taking 1 or N from each stream in each iteration
12:58TimMcclov3r: Yes, Java methods are not objects, so you can't pass them around like that.
12:58TimMc#(.contains "a" %) would be the equivalent
12:58clov3rTimMc: ok, well that;s good to know
12:58clov3rthanks :)
13:01justin_smithl1x: (doseq [stream-heads (apply map list streams) stream stream-heads] ...)
13:01justin_smithl1x: the problem with that is that it will stop when the shortest set of streams is done though...
13:02l1xhmm
13:02l1xi am thinking about creating a go-loop for each stream
13:02l1xand just send it to a channel
13:02tomjackyes!
13:02tomjackseqs don't seem right to me
13:02l1xdoseq is no good though, because it holds the head afaik
13:02l1xand you are running out of memory
13:03justin_smith,(for [stream-heads (map list [1 2 3] [4 5 6] [7 8 9]) stream stream-heads] stream)
13:03clojurebot(1 4 7 2 5 ...)
13:03l1x ,(for [stream-heads (map list [1 2 3] [4] [7 8 ]) stream stream-heads] stream)
13:03clojurebot(1 4 7)
13:03l1x:)
13:03justin_smithright
13:03l1xi was thinking about it a lot but it seems like channels are the best for this
13:03justin_smithdoseq does not hold the head
13:03l1xno?
13:04clojurebotno is tufflax: there was a question somewhere in there, the answer
13:04l1xinteresting, i got oom
13:04l1xand when i replaced it with loop it went away
13:04l1xmaybe it is not realted
13:04justin_smithit could have to do with how the args to doseq are being generated
13:04l1xi see
13:05crash_epDoes anyone know the reason a buffer must be explicitly provided when a channel is created with a transducer?
13:05justin_smithlike if you held onto the lazy thing that was passed to doseq
13:05l1xhmm i see
13:05justin_smithcrash_ep: because arity overload is the only function overloading we have
13:05l1xalright justin thanks anyway, i going to rewrite it with channels
13:06justin_smithl1x: that probably makes sense, yeah
13:06crash_epjustin_smith: but passing `nil` does not seem to create an unbuffered channel, as it would normally
13:06justin_smithodd
13:06crash_ep(in CLJS)
13:20dnolencrash_ep: that's just how it works, you have to transduce on something, buffer size 1, true for Clojure too
13:21crash_epdnolen: maybe I'm misunderstanding what a "buffer" is… I assumed `(chan)` creates a buffer of size 0.
13:22dnolencrash_ep: semantically unbuffered
13:22crash_epdnolen: right. Why shouldn't a transducer operate on values put on a semantically unbuffered channel?
13:22dnolencrash_ep: no
13:22dnolenit has to transduce on *something*
13:24crash_epdnolen: can you help me better understand what "transduce on" means? I thought transduction was an operation on values, but it sounds like something more nuanced than that.
13:24dnolencrash_ep: sorry, there are plenty of implementations you can read over now
13:25crash_epdnolen: ok, i'll take another look
13:25dnolenthe JS one provided by Cognitect that I wrote is particularly short
13:25dnolencrash_ep: https://github.com/cognitect-labs/transducers-js
13:26crash_epI guess the part I'm not getting is the relationship to buffer size.
13:26dnolencrash_ep: just replace "buffer" with "empty list"
13:26dnolendoesn't make any sense
13:31crazydiamondHi. Can I measure (say, in REPL) how long function takes to complete?
13:31sritchie,(doc time)
13:31crash_epdnolen: I thought transducers operated on the values as they pass through a channel, not a buffer.
13:31clojurebot"([expr]); Evaluates expr and prints the time it took. Returns the value of expr."
13:31sritchiecrazydiamond: that should work
13:31dnolencrash_ep: nope
13:31crash_epBut it sounds like you're saying that a transducer is a property of a buffer, not a channel
13:31justin_smithcrazydiamond: time for a semi-meaningful number, use criterium for proper micro-benchmarks
13:31dnolencrash_ep: transducers work on buffers yes
13:31crazydiamondsritchie, justin_smith great thanks!
13:31crash_epthen why don't we pass transducers to the `buffer` function instead of the `chan` function?
13:32crazydiamondI need to measure how long it takes to read file, so, it should be enough for me
13:32justin_smithcrazydiamond: criterium makes sure that JIT gets warmed up and shows you mean / average / max time the function took over many calls
13:33justin_smithwith the time function, you won't really see the influence of JIT, which can change things quite a bit
13:33dnolencrash_ep: that doesn't many any sense either
13:33dnolencrash_ep: the channel *uses* the buffer, it knows when and how to apply the transformer
13:34dnolens/many/make
13:34tbaldridgednolen: but the channel basically wraps the .add method of the buffer with the transducer,
13:36tbaldridgeso you could technically do it in the buffer, but I don't know that it would be any better than putting it in the channel.
13:36dnolentbaldridge: right which was my point, and less flexible if for some reason down the line something else needs to happen, encapsulation stinks blah blah blah :)
13:38crash_epThe relationship between these three things is not entirely clear to me, I'll have to study some more. Thanks dnolen tbaldridge
13:46SegFaultAXAny cyanite users around? The #cyanite channel is totally dead.
13:46SegFaultAXAnd no response yet from #graphite. #clojure, you're my only hope.
14:26AeroNotixSegFaultAX: yeah we use it, sup?
14:26SegFaultAXAeroNotix: Does it completely replace carbon-*?
14:26AeroNotixSegFaultAX: also, pyr is on #freenode
14:26SegFaultAXExcept maybe carbon c relay.
14:26AeroNotixSegFaultAX: pretty much
14:26SegFaultAXAeroNotix: I know, but all the channels are dead.
14:27AeroNotixSegFaultAX: pm him directly.
14:27AeroNotixhe's around
14:27SegFaultAXAeroNotix: Pretty much? Is there any need for carbon-cache or carbon-aggregate at all?
14:27AeroNotixSegFaultAX: I didn't set it up, I can ask
14:28AeroNotixSegFaultAX: nope, no need for either
14:29_tim__hi, is there something similar to the async/dropping-buffer where i can tell when an item is discarded? or throw an exception if the queue is full?
14:29AeroNotixSegFaultAX: if you want features from carbon-aggregate, you'll need
14:29AeroNotixsomething like carbon-c-relay to do the aggs for you
14:31SegFaultAXAeroNotix: Ok, that's fair enough.
14:31SegFaultAXAeroNotix: Thanks so much for your time.
14:31AeroNotixSegFaultAX: think nothing of it
14:31AeroNotixyay
14:31SegFaultAXAnyone here use Cyanite?
14:32AeroNotix:)
14:41ggherdov,(let [pair #((vector %1 %2))] (pair :a :b))
14:41clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector>
14:41ggherdovnot sure I understand why
14:41justin_smithggherdov: try expanding it
14:41justin_smith,'#((vector %1 %2))
14:41clojurebot(fn* [p1__53# p2__54#] ((vector p1__53# p2__54#)))
14:41ggherdovuh
14:41justin_smithnotice the problem?
14:41AeroNotixggherdov: you're calling the vector as a function
14:41justin_smithtoo many parens
14:42ggherdovthanks justin_smith AeroNotix
14:42justin_smith,([1 2])
14:42AeroNotixnp
14:42clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector>
14:42justin_smiththat's what it did
14:42ggherdovi see
14:42justin_smith,([1 2] 0) ; this works though
14:42clojurebot1
14:42ggherdovcool
14:50puredangerany time you see two ( ( together, you should pause and think about it to make sure that makes sense
15:00AeroNotixIf you were on a 19hr flight. What clojure{,script} documentation would you take with you?
15:03justin_smithAeroNotix: does grimoire have a standalone version yet? maybe just if you clone the repo?
15:03AeroNotixjustin_smith: good call
15:04justin_smithhttps://github.com/clojure-grimoire/grimoire
15:04AeroNotixthanks
15:04justin_smithalso, name-apropriate question of the day
15:04AeroNotix:)
15:05crack_userhello guys
15:05AeroNotixcrack_user: lo
15:06crack_userwhat is the best way I can check if all elements of collection A is in collection B
15:08crazydiamondHi. Is there alternate version to println, that would be truncating big structure (like by adding '...')?
15:08AeroNotix,(every? identity (map #{1 2 3 4} #{1 2 3 4}))
15:08clojurebottrue
15:08AeroNotixcrack_user: ^^ maybe?
15:09AeroNotix,(every? #{1 2 3 4} #{1 2 3 4}))
15:09clojurebottrue
15:09AeroNotixoh that's better^
15:10crack_userthat is it
15:10crack_userI just don't get the #{} syntax
15:11AeroNotixcrack_user: sets
15:11dnolencrack_user: based on your description the following would also work (clojure.set/subset? (set A) (set B))
15:12crack_userAeroNotix: but it also works with vectors and lists?
15:12AeroNotixcrack_user: no
15:12crack_user:/
15:12dnolencrack_user: you can re-read what I said
15:13dnolen,(clojure.set/subset? (set [:bird :dog :cat]) (set [:bird :cat :dog]))
15:13clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>
15:13dnolen,(require 'clojure.set)
15:13clojurebotnil
15:13dnolen,(clojure.set/subset? (set [:bird :dog :cat]) (set [:bird :cat :dog]))
15:13clojurebottrue
15:14AeroNotixI've always wondered why set is in its own namespace.
15:15crack_userdnolen: thx
15:21pepijndevosWith compojure, how do you get both the request body and url parameters?
15:22pepijndevos{body :body} and [id] combined
15:27puredangerPretty interesting new library from ye olde Nathan Marz https://github.com/nathanmarz/specter
15:27AeroNotixdude loves his macros
15:28pepijndevos{{id :id} :params body :body}
15:29puredangerAeroNotix: I don't think it uses macros?
15:30AeroNotixpuredanger: oh I saw the ALL and assumed
15:30AeroNotixmy bad
15:33zerokarmalefta lot of interesting variations of lens cropping up in the clojure space
15:33zerokarmaleftlenses*
15:34winkit uses com.rpl.specter whereas http://rpl.com seems unrelated - I've never seen that.
15:48puredangeryeah, that's weird. plus why even bother with com in that case?
15:49puredangerunless he's in the process of acquiring it :)
15:49clojurebotNo entiendo
15:52amalloycrazydiamond: you can bind *print-length* and *print-level* to change how println and prn handle large inputs
15:52amalloymaybe it's print-depth, i forget
15:52amalloy&(binding [*print-length* 5] (println (range 10)))
15:52lazybotjava.lang.SecurityException: You tripped the alarm! push-thread-bindings is bad!
15:52amalloy,(binding [*print-length* 5] (println (range 10)))
15:52clojurebot(0 1 2 3 4 ...)\n
15:53crazydiamondamalloy, thanks!
16:36sdegutisHi nerds. Got any recommendations for a superlative ergonomic keyboard? Price is no object. (It's a value.)
16:37amalloysuperlative, huh? you don't care if it's the best or the worst, as long as it's the most something?
16:38sdegutisamalloy: my dictionary says "of the highest quality or degree"
16:38sdegutisamalloy: so yes, the highest in quality
16:38amalloythat's a lame meaning. meaning 2 is the better one: expressing the highest or a very high degree of a quality
16:39amalloyie, worst is a superlative, the highest degree of the quality of badness
16:39sdegutisamalloy: in grammar, yes
16:39amalloygrammar is superlatively important
16:39sdegutisamalloy: perhaps I meant exemplary
16:40sdegutisamalloy: or supergood
16:40amalloydouble plus good
16:40sdegutisamalloy: now you're just making things up
16:42amalloy$google double plus good
16:42lazybot[Newspeak - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Newspeak
16:45sdegutisSo, ErgoDox?
16:46TimMcsdegutis: The DataHand is superlative along the axis of price.
16:46TimMcand unavailability, probably
16:46sdegutis~guards
16:46clojurebotSEIZE HIM!
16:48TimMcThe Maltron is the most UK one I know.
16:49TimMcsdegutis: And the Atreus is the most Clojure keyboard.
16:49sdegutisTimMc: says how?
16:49TimMcWell, technomancy makes it.
16:50sdegutisTimMc: so true
16:52TimMcI was going to get a fancy keyboard but I got physical therapy instead.
17:12xemdetiaI got a $10 and grew a beard so I have less RSI from contemplative beard stroking
17:15rpauloI have a beard and that didn't help
17:31sdegutisxemdetia: sounds reasonable alternative; thanks
17:38bigsTimMc, sdegutis: i have a pretty bad (diagnosed) case of carpal tunnel in both wrists. i've been using the kinesis advantage for about six months, now, and it's been absolutely astounding
17:38bigscould not recommend it highly enough
17:39sdegutisbigs: hmm, thanks for the testimony
17:39sdegutisbigs: it looks like it'd be painful on the wrist though cuz it rests on the flat surface
17:39bigsthe key is getting a chair w/ elbow rests
17:40bigsthat you can raise up highly enough so that your forearms are flush
17:40sdegutisbigs: clever
17:40sdegutisbigs: but im about to build a standing desk this weekend
17:40bigsi've also been in physical therapy for 4 months
17:40sdegutisbigs: so i dunno how thats gonna play into it
17:40bigsah perfect
17:40bigsyou can just adjust the height
17:40sdegutisoh good point, i should make the height adjustable
17:40bigsi actually just got my ergodox from the recent massdrop
17:40bigsbut haven't put it together
17:41sdegutismassdrop?
17:41bigsi'm looking fwd to having it as my second keyboard
17:41bigsaye massdrop.com
17:41bigsafaik the only place selling ergodox kits
17:41sdegutisaww requires account
17:41sdegutisdang
17:41bigshaha
17:41scottj?mode=guest_open might work
17:42bigsbut yeah i seriously could never have imagined the impact the kinesis had
17:42sdegutisbigs: the tons of keys by the thumbs seems strange tho
17:42bigsthat's the best part for me -- a lot of my CTS stems from overuse of the thumbs
17:42sdegutisbigs: i can understand ctrl+shift+alt+meta (two per thumb) but 10 total? wth?
17:42bigsi.e. bending them under the hand
17:42bigsto hit the modifier keys
17:42sdegutisbigs: oh yeah me too
17:42bigsw/ a layout like this, your hands remain open
17:43sdegutisbigs: i have apple kbd and reading left thumb to left Cmd key is big cause of pain
17:43bigswhich reduces strain a lot. only takes maybe 5 days to get used to
17:43sdegutissure
17:43sdegutisi liked atreus's idea of putting modifiers near thumbs, but atreus has too few keys 4me
17:43bigsaye
17:45sdegutisdang, no chance of getting ergodox soon cuz the drop ended
17:45sdegutiswsa hoping to get new kbd by monday
17:45scottjit takes 1-2 months after the drop ends anyway. they have a drop roughly once a month
17:47bigsyeah
17:48bigsthat's why i got a kinesis :P
17:48bigsneeded a solution immediately
17:48scottjbigs: do you use emacs btw?
17:48bigsi'm a vimmer
17:48bigsbut i use emacs w/ evil mode
17:48bigsmy cofounder is a full on emacs user w/ kinesis
17:52sdegutisbigs: it looks like the alt/ctrl keys on kinesis/adv would be hard to reach with thumb & require stretching
17:53bigsah he maps the right ctrl to meta
17:53bigsto take care of that
17:53bigsah -- also the kinesis is hardware programmable
17:53bigswhich is awesome
17:53sdegutiswhats that mean?
17:53sdegutisis that kind of like atreus's firmware?
17:53bigscan reprogram keys on the unit itself
17:53bigsno software
17:53sdegutisre https://github.com/sdegutis/atreus-firmware
17:54sdegutisbigs: you use querty or colemak?
17:54sdegutislol @ phonic typo
17:55sdegutisi wondered why that felt strange to type
17:55bigshaha livin that qwerty life, but would love to go to colemak
17:55sdegutisok
17:55bigsgot a lotta c++ to write, tho haha
17:55sdegutisthx bigs 4 ur hlp
17:55bigsno time to relearn!
17:55bigsabsolutley -- feel free to pm me whenever. this is something i've spent a lotta time on
17:56bigswhen my CTS was at its worst, my hands were so swollen i couldn't form a fist
17:56sdegutisbigs: doesnt it hurt to have your wrists against the flat surface of it all the time?
17:56sdegutisre https://www.kinesis-ergo.com/shop/images/1466/advantage-side-hands.jpg
17:56bigsit comes w/ two adhesive wrist pads
17:56sdegutisoh nice
17:56bigsfitted for that plastic area -- quite comfortable and seem to age well
17:57scottjalso they recommend not resting your palms on it or the pads all the time while typing
17:57sdegutisy4?
17:57bigsyeah
17:57sdegutiswhy for
17:58bigsdefinitely, scottj - the concavity makes it easier, too
17:58bigsreleaves pressure on the carpal tunnel
17:58scottjsdegutis: presumably same reason you're not supposed to do it on a normal keyboard
17:58sdegutisbigs: where do your thumbs rest when not using those keys (ie ur just reading)?
17:59bigsspace & backspace
17:59sdegutisbigs: in between the two thumb-key groups, or outside them,?
17:59sdegutisooh
17:59sdegutisi guess if it has heavy keys then thats fine
17:59scottjprobably quite convenient for reading, since I think lots of apps support those two keys for forward and back a page
17:59sdegutisie requires pressing harder-ish
17:59bigsyeah it has mechanical switches
17:59sdegutisphew
17:59bigsand the springs are good
17:59sdegutisi wonder if my boss will buy it or if i have to buy it meself
18:00bigsshould be an easy sell to the boss
18:00sdegutisbut its like ~$250
18:00sdegutisoh wait $300
18:01bigsso like... 1.5-2 hrs of dev time hehe
18:01sdegutisoh nic, they sell foot pedals!
18:01bigsyep :)
18:01scottj$269 new w/ free ship off their ebay or amazon page. slightly less for a refurb that someone used for 10 minutes.
18:03sdegutisheh
18:03bigsi gotta get back to it, but good luck!
18:03sdegutiscya thx
18:42vasHello
18:45vasThis is more of a datomic-specific question -- is there a constantly running database process in another terminal?
18:54justin_smithvas: it may or may not run in a terminal. Usually there is at least one db process, yes.
18:56gphilipphello
18:56l1xjustin_smith: i rewrote the code that we talked about earlier with sync and channels, it does 30K req/s, the older version did 50K req/s. I am trying to dig into async and see if I could tune the code further
18:57l1xbut now, i have a fully fledged idiomatic Kafka client in Clojure \o/
18:57l1xthe other project, is just ignoring these things so that codebase does not work with multiple Kafka streams
18:57vasjustin_smith thanks. (=
18:57justin_smithl1x: one option if you really need max throughput is to directly use threads reading from native concurrent blocking queues
18:58justin_smithor one queue shared by the threads running the code, each one taking items off
18:58justin_smithwhatever makes sense for your setup
18:58l1xjustin_smith: right
18:58l1xjustin_smith: https://gist.github.com/l1x/2a2b794379752199cd4b
18:59justin_smithcore.async makes managing complex asynchronous stuff much less brittle, but perf wise sometimes a dedicated thread with a normal queue does the trick
18:59l1xit is using async/thread + go-loop
18:59gphilipphi
18:59l1xit might not be ideal for this usecase
18:59l1xi might just use a normal loop + recur
19:00l1xbut i am pretty happy that the out of the box performance is accetable
19:01gphilippHow can I set *print-right-margin* once and for all in my repl session w/o using (binding ...) macro. I've tried (set! ...) but it doesn't work (Can't change/establish root binding of: *print-right-margin* with set) ?
19:10ToxicFrogIs there a "dissoc-in"?
19:10avshalom,(+ 2 2)
19:10clojurebot4
19:11justin_smithToxicFrog: I think it exists in some util libs, but there is also update-in + dissoc
19:12BronsaToxicFrog: https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj#L62
19:12justin_smith,(update-in {:a {:b 1}} [:a] dissoc :b)
19:12clojurebot{:a {}}
19:12justin_smith,(update-in {:a {}} [:a] dissoc :b)
19:12clojurebot{:a {}}
19:13justin_smith,(update-in {} [:a] dissoc :b)
19:13clojurebot{:a nil}
19:13justin_smiththat last one is where it gets tricky
19:19gastoveThis might be a terribly noob question, but: is it possible to have a defprotocol, implemented in a defrecord, that takes an additional argument that isn't part of the record's constructor?
19:21amalloygastove: yes. protocol functions take one 'this argument, which is the record, and from which you can get all the record's fields, and any number of other arguments you want
19:21gastoveSay... (defprotocol Foo (bar [x y])) (defrecord Baz [z] Foo (bar [x y] (println x y z)))
19:21Bronsa,(defprotocol Foo (bar [x y]))
19:21clojurebotFoo
19:21Bronsa,(defrecord Baz [z] Foo (bar [x y] (println x y z)))
19:21clojurebotsandbox.Baz
19:21Bronsa,(bar (Baz. 1) 2)
19:21clojurebot#sandbox.Baz{:z 1} 2 1\n
19:22gastoveamalloy: AH. Okay.
19:22gastoveamalloy: somehow, I missed the part about `this` arguments, so all my arities are off.
19:55ToxicFrogHmm.
19:55ToxicFrogSo I want something similar to cond, that evaluates a sequence of (condition, value) pairs.
19:56ToxicFrogBut I want it to return not only the value, but the corresponding condition as well.
19:56ToxicFrogIs there a thing for this?
19:57ToxicFrogHmm. Condp looks like almost what I want.
20:04amalloyToxicFrog: condp with the :=> keyword or whatever it is might suit, but it'll depend on what conditions you're testing
20:28bashedHas anyone noticed slow lein on linux? I'm developing in both OS X and linux using Oracle Java 8 but the linux system has a very slow compile time. The machine it is on is not even comparable to the mac (more powerful)
20:28amalloybashed: SSD?
20:29bashedYeah
20:29mmitchell,(map byte "foo")
20:29clojurebot(102 111 111)
20:30mmitchell(map byte "foo∂")
20:30bashedamalloy: Hah, thanks I guess. I'm using an SSD but my 'Dev' folder is mapped to a HD. I guess I should have thought about that sooner
20:30mmitchellhmm yeah, anyone know how to map a string with unicode to an array of bytes?
20:31amalloy,(.length "foo∂")
20:31clojurebot4
20:31amalloy,(seq (.toBytes "foo∂"))
20:31clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: toBytes for class java.lang.String>
20:31amalloy,(seq (.getBytes "foo∂"))
20:31clojurebot(102 111 111 -30 -120 ...)
20:32amalloygets you the bytes in UTF-8; you can ask for other encodings if you are a heathen
20:32mmitchellnice, thanks amalloy
20:35mmitchellamalloy: oh hmm, and then back to a string? (map char ..) => java.lang.IllegalArgumentException: Value out of range for char: -30
20:35amalloymmitchell: why are you converting a string into bytes and back into a string?
20:35amalloyi mean it is not an impossible thing to do but it is weird
20:36mmitchelljust curious! :)
20:36amalloy,(String. (.getBytes "foo∂"))
20:36clojurebot"foo∂"
20:36mmitchellgood grief, that looks so obvious now. Thanks amalloy
20:36amalloyand if you already have the seq of bytes, produced by (seq (.getBytes "foo∂")), you can call (byte-array xs)
20:37mmitchellok nice
20:54Shayanjmanyone know if there's a canned algorithm to determine the minimum number of circles with fixed radius R to fill the area of a larger circle of some arbitrary radius N > R?
21:12TravistyShayanjm: That sounds like a hard problem
21:12gfredericksShayanjm: tight minimum? cuz you can get a lower bound by just dividing the areas
21:12Shayanjmgfredericks: would like to maximize for coverage as well as # of circles necessary
21:13Shayanjmthinking overlapping doesn't really matter
21:15gfrederickswhat does "maximize for coverage" mean? you already required filling the area
21:16TravistyShayanjm: It sounds related to the disk-covering problem: http://en.wikipedia.org/wiki/Disk_covering_problem
21:16Shayanjmgfredericks: given R is fixed, there's a very good chance that full coverage is impossible given non-overlapping circles
21:16Shayanjmin the case of overlapping, sure full coverage is totally possible
21:17gfrederickshow is it possible at all without overlap??
21:17lazybotgfredericks: Uh, no. Why would you even ask?
21:17TravistyShayanjm: If you’re talking about packing the smaller circles into the bigger one without overlap, the problem is certainly hard
21:18TravistyShayanjm: http://en.wikipedia.org/wiki/Circle_packing_in_a_circle
21:19Shayanjmgfredericks: impossible to get 100% coverage with non-overlapping circles
21:20Shayanjmbut you can get fairly close depending on R
21:20ShayanjmTravisty: Looking, thanks
21:20Shayanjmgoing to rough out an implementation i think
21:20TravistyIf you manage to solve either problem exactly, I think that would be quite an accomplishment
21:21ShayanjmTravisty: Probably won't be near exact, but hopefully "good enough" to get the data I need
21:21Travisty(i.e., finding the smallest number N of circles of radius r required to cover a circle of radius R, or finding the maximum number of non-overlapping circles of radius r that you can fit in a circle of radius R)
21:22Travistyyou might be able to come up with some bounds that aren’t too bad
21:23ShayanjmTravisty: Yeah that's the idea. I want to figure out how "rough" my implementation can be and still have half-decent results
21:24pdkgenetic algos give you a good amount of leeway to be "rough"
21:24Travistypdk: Do you really think genetic algorithms are a good idea for this problem?
21:25TravistyThere are very simple ideas that seem like they should be within a factor of 2
21:25ShayanjmI think trying to implement genetic algos to fit this model would be more problematic than helpful at this point
21:25Travistyi.e., laying the circles down in grid that is just fine enough that there are no empty spaces
21:27TravistyYou know that you need at least (R/r)^2 circles, and you could compute the number of circles you use in that grid, which amounts to working out how close the points in your grid need to be and how many of those points land in the circle of radius R
21:27TravistySeems plausible that it will also be on the order of (R/r)^2
21:28ShayanjmTravisty: I'm going to try throwing something into code and seeing what sticks. In the middle of a seminar right now so can't really sit down and REALLY think about the problem
21:29Shayanjmbut in ~30 mins i'm going to see if I can implement a hexagonal layout for overlapping circles, and then trial-and-error non-overlapping and seeing what happens
21:30TravistyYou might want to spend some time deciding what you want to optimize. If you don’t require that the larger circle be entirely covered, then you need to find some way to trade between the competing objectives of coverage and using only a few circles
21:31ShayanjmTravisty: that's probably where a genetic algorithm would come in handy
21:32TravistyYou shouldn’t need a genetic algorithm to state the problem you want to solve
21:59justin_smithShayanjm: what you want is a packing algorithm I think
22:00justin_smithpacking algorithms are about successively placing items, with goals of taking up minimal space, reducing overlap, whatever.
22:03justin_smithor filling the space to a maximal covered percentage with a minimum number of items, sounds like your problem.
22:05justin_smithnot directly related, but an algo with a really cool output http://cs.stackexchange.com/questions/12925/circle-packing-algorithm-used-by-percolator
22:14Shayanjmthanks justin_smith
22:14Shayanjmdo you know of any clj circle-packing implementations?
22:14justin_smithShayanjm: no, but I worked on one for rectangle packing (basically trying to do something like masonry.js in cljs)
22:15Shayanjmooh, justin_smith do you have code samples offhand that you don't mind me looking at?
22:15justin_smithit's open source
22:15justin_smithhttps://github.com/prismofeverything/netnetnet
22:16justin_smithwait... this isn't looking like the finished project at all
22:16justin_smithone moment
22:17justin_smithShayanjm: correction, this is the repo - https://github.com/prismofeverything/tesselax
22:17Shayanjmgreat, thanks justin_smith
22:18justin_smithit's designed with the intention that eventually layout algos would be swapped out
22:18justin_smith(I wanted to do packing starting in the center and building out instead of starting at top left and moving down/right)
22:19Shayanjmjustin_smith: turns out that's exactly how I want to attack my own packing problem
22:19justin_smiththe inside out?
22:19justin_smiththe issue you will see with our code base (likely) is that all of it implies rectangular geometry
22:20ShayanjmYeah that's fine, I just wanted to see how you've structured your implementation
22:20justin_smithbut maybe you can salvage it and add non-rectangular overlap / positioning rules
22:20justin_smithOK
22:20justin_smithwe did make it theoretically pluggable
22:20justin_smithit is just that we didn't try plugging anything yet :)
22:20ShayanjmI probably won't reuse any/much of your code, but do you want attribution if I do?
22:20justin_smithit's EPL
22:20justin_smithjust follow the rules of the EPL if you use our code
22:20ShayanjmAhh yeah totally didn't look @ the license
22:23justin_smiththe EPL is very permissive about redistribution, and even combining with non-epl code
22:35l1xis there a way to override what happens when a java lib throws an exception in a different thread in Clojure?
22:36justin_smithl1x: like maybe wrap the code for that thread in a try/catch?
22:36justin_smithor is the java lib creating the other thread offering you no option to modify the code running the thread?
22:38l1xi can try the try/catch but if the exception is caught in the lib it does not make it to clojure
22:38l1xat least this is my understanding
22:51bashedHow do I use pprint to print a nested map as compactly as possible? (less new lines)
23:46l1xDon't know how to create ISeq from: scala.collection.immutable.Stream
23:46l1xdamn
23:46l1xnot everything is sequable??
23:46lazybotl1x: Definitely not.
23:46l1xi know bro, and it is sad
23:47justin_smithl1x: did you try calling seq on it?
23:47l1xyeah
23:47justin_smithhmm...
23:47l1x(seq (.toSeq iterator)
23:47l1xthe problem is that the lazy-seq implementation is broken
23:47l1xit hold onto the head
23:47justin_smithwhose?
23:47l1xholds*
23:48l1xi am shoving you
23:48l1xshowing
23:48l1xjeez my english degrades like
23:48l1xhttps://gist.github.com/l1x/7dc6f42c43d191bcfe41
23:49l1xi should use (rest iterator)
23:49l1xi guess, but it is not sequable and you cant do that