#clojure logs

2016-02-04

00:31Tilkhello
00:40hammerhey there
00:41hammerany tips for newbies?
00:42hammerhello?
00:42clojurebotBUENOS DING DONG DIDDLY DIOS, fRaUline hammer
01:00lambda-11235hello?
01:00clojurebotBUENOS DING DONG DIDDLY DIOS, fRaUline lambda-11235
01:01lambda-11235What's fRaUline?
01:58kenrestivogerman for "miss"?
07:57dysfunwhat are my alternatives to core.async in clojurescript if i want something with a very light footprint and i simply want channels and none of the async stuff?
07:57justin_smithdysfun: totally locking up because you have no threads
07:58dysfunlol
07:58justin_smithdysfun: more seriously, promises and callbacks? kind of sucks though
07:58justin_smithbut you won't get channels
07:58dysfun*sigh*
07:58dysfunare there any more light footprint options?
07:59dysfun(i don't want a huge js file out of the other end)
08:00justin_smithprobably not in cljs, but you might have luck with js-csp or something, there's a few libs that seem to try to do this, but I don't have a size comparison
08:05dysfungosh, the only current browser they don't work in is opera mini
08:06justin_smiththat sounds interesting, and agents implicitly have queues that are effectively channels, so there you go!
08:07dysfunthat was what i was thinking
08:07dysfunthere's a sort of odd similarity between actors and agents
08:08justin_smithagents are inside out actors
08:08justin_smithall the logic is always on the outside, passed in
08:13dysfuni think a channel can be accomplished with a persistentqueue and an atom
08:14justin_smithswap! retries and agents lock instead of retrying, so I wouldn't use an atom
08:15justin_smithwell, maybe retrying on the queue operation is OK
08:26dysfunjustin_smith: for a channel, not an agent
08:26justin_smithdysfun: the tricky thing with using an atom for a channel is you want a single op that returns the top item while removing it
08:27justin_smithdysfun: you'll find a pair of refs handles this much more cleanly
08:27dysfungreat. thanks.
08:27dysfunnow i just have to write an stm
08:27justin_smithactually just one ref, but you need a transaction that alters the channel while removing the next item (for reads)
08:28dysfunnot helping
08:28justin_smithwell given the lack of threads you don't even need an atom
08:28justin_smithjust punch the state in the gut and accept what you get
08:28dysfunyes, but atoms are sensible primitives
08:28dysfunand obviously they're quite fast
08:29justin_smithgiven the absence of threads, what do they do for you?
08:29dysfunthey provide a nice convenient interface over immutable data
10:22Glenjaminyou still need somewhere to mutate, and cljs doesn't have vars
10:41jsabeaudryLet's say I want to (swap! a assoc :b :c) (swap! a update :d conj :e), would the clean way to write this be: (swap! a #(-> % (assoc :b :c) (update :d conj :e))) ? Is there a cleaner way?
10:50justin_smithGlenjamin: sure, but I also find it funny cljs has atoms but no vars
11:56engblomI am curious of why Clojure is faster when run with 'lein run' rather than 'java -jar whatever-standalone.jar'?
11:56engblomI am using (time ....) to measure, so the loading is not taking into account.
11:56engblomnot need to be taken*
11:59justin_smiththe java -jar version doesn't have hotspot turned on, hotspot has short term costs (the price of gathering the metrics and calculating optimizations) that are balanced by the optimizations it brings in later
11:59justin_smitherr, I mean the lein version has hotspot turned off
12:00justin_smithso it could be a difference caused by hotspot getting ready to optimize (or even optimizing) but not doing enough yet for you to see the difference
12:00engblomThanks! That explains
12:00engblomI will check my simple benchmark with a bit bigger loop
12:01justin_smithengblom: this could explain it - if you use (criterium.core/bench ...) instead of (time ...) you'll get a better answer
12:01justin_smithcriterium is good at making sure hotspot has kicked in (if it can)
12:08phillordI found several orders of magnitude difference between criterium and time
12:08engblomJava HotSpot(TM) Client VM warning: TieredCompilation is disabled in this release.
12:08engblomSo the hotspot is never used for me...
12:08justin_smithengblom: right, lein did that
12:08justin_smithjava -jar won't give you that message
12:08phillordbenchmarking well is very hard -- in general, you need to launch multiple times, with randomisation. Unless it's really really vital, I wouldn't bother.
12:08justin_smithso the java -jar gets optimized, lein run does not
12:10justin_smithphillord: what's wrong with using criterium with representative inputs? the reason it's different from time is because it's avoiding a bunch of noise sources that time is prone to
12:11phillordjustin_smith: nothing wrong with it, just saying that the results you get might not reflect what happens outside of criterium
12:11justin_smithphillord: I'd say contrarywise that time doesn't reflect the results of the thing you are supposedly timing
12:11dysfunjustin_smith: so i ended up using compare-and-set!
12:12justin_smithdysfun: ah, that sounds right
12:12engblomphillord: I am trying to understand so I could be able to get the raspberry pi gpio library a bit faster. Currently it runs at about 42kHz if you do nothing else than turning on and off a led. Compare it to this: http://codeandlife.com/2015/03/25/raspberry-pi-2-vs-1-gpio-benchmark/
12:12engblomphillord: The only thing slower is shell...
12:13justin_smithengblom: oh, another gotcha here is that the ARM jvm is hardly optimized compared to the x86 jvm
12:14justin_smithso you'd want to be sure any benchmarking is happening on the ARM device
12:14engblomjustin_smith: I am doing all the benchmarking at the rpi2
12:14justin_smithcool
12:15phillordengblom: your running clojure on a PI? What's your boot time?
12:15justin_smithphillord: in my experience it's within usability ranges as long as you don't use lein - under 10 seconds
12:15justin_smithwith lein it's insane and useless
12:16justin_smithminute long startups
12:16phillordjustin_smith: I'm surprised -- I just assumed it would be awful and never tried
12:16justin_smithclojure is remarkably snappy when you get the tooling out of the way
12:17engblomphillord: I measured time to get a repl: 1m 6s
12:17justin_smithstill a slow tool, but not like c++ compiler slow
12:17dysfunhuh, does & not work in protocols?
12:17dysfunor is there something special about a function called >! ?
12:18phillordengblom: not so bad -- about the same as my netbook
12:18justin_smithdefinitely nothing special about >!
12:18engblomphillord: It is fully acceptable as I anyway do not need to restart the repl during development. I send everything over with vim fireplace...
12:19dysfunclojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException: No single method: _GT__BANG_ of interface: irresponsible.baud.LineProto found for function: >! of protocol: LineProto, compiling:(/var/folders/k6/glc05svd5d194k8kgqfwkrph0000gn/T/boot.user9054690600505278700.clj:1:1)
12:19phillordengblom: learn something every day!
12:19dysfunhttps://gist.github.com/jjl/3b7f4ed3bd41f8c10079
12:19engblomphillord: This is my library (the first I ever made in clojure): https://github.com/engblom/gpio
12:21justin_smithdysfun: I'm getting "no single method" no matter how I try to use & in protocol method arg lists
12:21dysfunwell that's quite irritating
12:21justin_smithdysfun: haha, time to do a clojure.core (defprotocol ITedious (foo [this]) (foo [this that]) (foo [this that other]) ....)
12:22phillordI might well give that a go, looks like fun
12:22dysfunjustin_smith: hrm, do you not have to implement all of a protocol then?
12:22justin_smithdysfun: there is no requirement that one implement every method on a protocol
12:22justin_smithdysfun: of course you get a runtime error if you call one that was not implemented
12:22dysfuni think i can use that
12:23justin_smiththis goes for Interfaces too in clojure (unlike javac)
12:25engblomphillord: By the way, if you ever run Clojure on RPI2, make sure you use oracle-jdk. Openjdk will take more than 7 minutes for repl and is unstandable slow on arm.
12:26phillordah, that's interesting
12:26engblomOpenjdk lacks JIT
12:26kwladykajustin_smith i back to "old" topic.... http://clojure.github.io/tools.logging/#clojure.tools.logging.impl/get-logger so (get-logger (find-factory) logger-ns) <- how is it works? get-logger i understand get implementation of Factory by namespace... but how is it works? Each namespace can have another Logger? How can i know Logger for third party module then?
12:26engblomJIT for arm
12:26justin_smithengblom: the default PI os for rpiII is oracle iirc
12:26phillordI'd heard that overtone has a 6-7 min boot time on PI, but that was a while back. Maybe this is why.
12:27engblomProbably. OpenJDK is running in interpreted mode on ARM, while Oracle-JDK is able to use JIT.
12:27justin_smithkwladyka: for java logging, loggers are configured per class
12:27justin_smithkwladyka: java doesn't even have namespaces
12:28justin_smithkwladyka: this is why the solution I was trying to encourage you to use was pure interop - because the java stuff isn't using the clojure.tools.logging.impl stuff
12:31kwladykajustin_smith not sure if i understand. Clear Java solution (LoggerFactory/getLogger Logger/ROOT_LOGGER_NAME) doesn't need namespace, but Clojure solution use namespace?
12:34kwladykaplease correct me if i dont understand: this solution http://stackoverflow.com/questions/13760095/java-dynamically-change-logging-level turn off logging for all handlers where handlers are... namespaces? They use empty string here Logger.getLogger( "" )
12:36rhg13520s to run nil on rpi1 with openjdk, hmm
12:37kwladykajustin_smith or maybe do you know site where i can clearly understand that? :)
12:38engblomrhg135: If you have a rpi1, could you please benchmark my gpio library? I would want to know if it is usable on rpi1. I can paste quickly somewhere some code for you to test.
12:39rhg135Yeah, engblom, that's fine.
12:39engblomrhg135: http://pastebin.com/dTKKDcKc
12:40engblomrhg135: That would turn on and off a led 1 000 000 times as fast as possible.
12:42rhg135With criterium? If so, idk if it'll be done today
12:44engblomrhg135: For me it is already enough if you run that program exactly as it is without criterium. That will already tell if it is usable
12:44rhg135and I don't need anything on the gpio port?
12:45engblomrhg135: no, you do not need anything
12:45justin_smithkwladyka: had a meeting, back now
12:46kwladykajustin_smith sorry if my question or not on high level. Just for some reason it confuse me.
12:46justin_smithkwladyka: clojure.tools.logger has per-namespace config for logging, java logging has per package and class configs. But you can get the "root" which they all default to.
12:46rhg135Cool, I will go run that
12:47justin_smithkwladyka: jvm logging is a mess, sorry.
12:47kwladykajustin_smith oh now it is more clear
12:47justin_smithOK
12:47kwladykajustin_smith so it is impossible to log off flyway using clojure.tools.logger ?
12:48justin_smithkwladyka: if you just want to set verbosity for java logging, you can use a logging.properties file for whichever logging backend is being used (there are a few out there)
12:49justin_smithkwladyka: clojure.tools.logger is just a set of macros for using the java logging from clojure
12:50justin_smithif you set up clojure.tools.logger to control the same logging subsystem that flyway is using, then you could use clojure.tools.logging to control flyway's verbosity
12:50justin_smithbut to me it seems easier to just configure the logger flyway is using directly
12:50justin_smitheither with a properties file if you want to set it statically, or the code I shared before for altering the level at runtime
12:52kwladyka(:import org.slf4j.LoggerFactory) (ch.qos.logback.classic Logger Level)) (.setLevel (LoggerFactory/getLogger Logger/ROOT_LOGGER_NAME) Level/WARN))) <- like that?
12:52mpenet"clojure.tools.logging" :>
12:52justin_smithyup, where WARN could be ERROR or whatever if you chose
12:52justin_smithmpenet: yes, right, he started it
12:52justin_smithhaha
12:53kwladykajustin_smith ok so the question is... how can i be sure flyway will use exactly slf4j?
12:54kwladykaand how to set this only for block of code
12:56justin_smithslf4j is an abstraction layer over a few different loggers
12:56kwladykajustin_smith oh is it like clojure.tools.logging?
12:56kwladykabut for Java
12:57kwladykaand how can i set this only for block of code in tests? i don't want turn off logging for everything
12:57kwladykaonly for flyway reset database
12:58justin_smithclojure.tools.logging is a wrapper over slf4j, commons-logging, log4j, java.util.logging, slf4j is a wrapper over log4j and java.util.logging and the whole world of java logging is so messy it makes me angry
12:58jweissi was given this code to create a sorted set of ranges, like #{[1 2] [4 5] [6 7]}, but it's buggy: (apply sorted-set-by (fn [[from-a to-a] [from-b to-b]] (< to-a (dec from-b))) rs)
12:58justin_smithkwladyka: that code snippet doesn't turn the logging off, it just adjusts the level of logging, you can change it back afterward
12:59jweissnot sure what the issue is, i don't know what a comparator is supposed to do. i thought it returns an int, not just true or false?
12:59justin_smithjweiss: you don't need sorted-set-by, sorted-set will handle vectors just fine
13:00jweissjustin_smith: ok, just for my edification, is that comparator bad or is that how it's supposed to be?
13:00justin_smith,(instance? java.util.Comparator >)
13:00clojurebottrue
13:01mpenetkwladyka: you can silence it via a log4j.properties file
13:01justin_smithmpenet: he wants it only in one block of code
13:01mpenetjust add en entry where it logs only "error"
13:01mpenetah
13:01justin_smithwhich is why the thing with Logger/ROOT_LOGGER_NAME etc. the little interop with ch.qos
13:02justin_smith,(.compare > 1 2)
13:02clojurebot1
13:02justin_smith,(.compare < 1 2)
13:02clojurebot-1
13:02justin_smithjweiss: maybe that helps? ^
13:03justin_smithjweiss: sorted-set-by is going to use the function provided as its comparator, and call compare
13:03jweissjustin_smith: yep, thanks. i don't exactly see what's wrong with the code above, but i'll try just plain sorted set
13:04justin_smithjweiss: yeah, sorted-set should work, because compare already knows how to sort two element vectors
13:04justin_smith,(sorted-set [6 7] [1 2] [4 5] [3 4])
13:04clojurebot#{[1 2] [3 4] [4 5] [6 7]}
13:07justin_smithjweiss: fun thing is that all clojure functions implement comparator
13:07justin_smith,(.compare list 1 2)
13:07clojurebot#error {\n :cause "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :at [clojure.lang.AFunction compare "AFunction.java" 56]}]\n :trace\n [[clojure.lang.AFunction compare "AFunction.java" 56]\n [sun.reflect.NativeMethodAccessorImpl invoke0 "NativeMethodAcc...
13:07justin_smithoops!
13:07justin_smithdoesn't always work
13:07justin_smith,(.compare (constantly true) 1 2)
13:07clojurebot-1
13:07jweissjustin_smith: using sorted set doesn't behave correctly with the function I have that will combine ranges: like (add-interval #{[1 2] [4 5]} [3 3]) should be #{[1 5]}
13:08jweissthen again, the sorted-set-by didn't work right either, but worked better :)
13:08justin_smithjweiss: you want the sorting operator to accomplish that?
13:08justin_smithjweiss: the sorting operator can decide which items are redundant, and where to put the ones that remain, but it cannot alter any of the values in the coll
13:09justin_smithmaybe you want a new custom collection type instead
13:09jweissjustin_smith: right the other function i have would disj from the set and then conj a new item
13:10justin_smithjweiss: OK, but the sorting function can only order things, and decide on a pair by pair basis if things are >, <, or =
13:10justin_smithit can't merge things or eliminate based on a three way comparison
13:10justin_smithbecause .compare is called on two items at a time
13:10jweissjustin_smith: the other function call subseq, eg (subseq ranges <= [from from] <= [to to]) which i also don't quite understand how that works
13:11justin_smithOK, the sorted-set should give you [1 2] [3 3] [4 5] in that order, your code has to decide what it can merge
13:12justin_smithand that ordering is perfect for merging via reduce
13:13jweissyeah good point, i don't understand how the function i was given works but i see how to do it with reduce
13:17justin_smith,(reduce (fn [ranges [start end :as el]] (let [[s e] (peek ranges)] (if (> start e) (conj ranges el) (conj (pop ranges) [s end])))) [[1 1]] [[1 3] [3 3] [3 5]])
13:17clojurebot[[1 5]]
13:18justin_smith,(reduce (fn [ranges [start end :as el]] (let [[s e] (peek ranges)] (if (> start e) (conj ranges el) (conj (pop ranges) [s end])))) [[1 1]] [[1 3] [3 3] [3 5] [7 10] [9 20] [420 666]])
13:18clojurebot[[1 5] [7 20] [420 666]]
13:18jweissexcellent, thanks
13:18jweiss(inc justin_smith)
13:18justin_smithsadly lazybot is not with us
13:28kwladykajustin_smith logger factory depend on system where app is run?
13:47jweiss,(reduce (fn [ranges [start end :as el]] (let [[s e] (peek ranges)] (if (> start e) (conj ranges
13:47jweiss el) (conj (pop ranges) [s end])))) [[1 1]] [[1 3] [4 5] [7 9] [8 8]])
13:47jweissugh
13:47clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
13:47jweiss,(reduce (fn [ranges [start end :as el]] (let [[s e] (peek ranges)] (if (> start e) (conj ranges el) (conj (pop ranges) [s end])))) [[1 1]] [[1 3] [4 5] [7 9] [8 8]])
13:47clojurebot[[1 3] [4 5] [7 8]]
13:48jweiss,(reduce (fn [ranges [start end :as el]] (let [[s e] (peek ranges)] (if (> start e) (conj ranges el) (conj (pop ranges) [s end])))) [[1 1]] [[1 3] [4 5] [7 9] [6 6]])
13:48clojurebot[[1 3] [4 5] [7 6]]
13:48justin_smithjweiss: yeah, the reduce fails if the items are not sorted
13:48jweissah right
13:48amoeI would like to get pretty-printed output like 'pprint' from clojure.tools.logging and also use a format string like 'logf', and not have to explicitly pretty-print in every call, and also avoid premature evaluation of the pretty-printing depending on the log level. Any way to achieve this?
13:49justin_smithjweiss: you'd also see issues if any of the ranges were sorted wrong
13:49justin_smithor if they contained things not numbers
13:49jweissjustin_smith: right, i can guarantee the ranges will be correct
13:50justin_smithamoe: sounds like a cool logging lib you're about to implement
13:50amoejustin_smith: I thought so :)
13:51amoeI think maybe I can use this to help out https://github.com/AvisoNovate/pretty/blob/master/src/io/aviso/logging.clj
13:52amoeWill check into this tomorrow, I think
14:00jweiss,(reduce (fn [ranges [start end :as el]] (let [[s e] (peek ranges)] (if (> start e) (conj ranges el) (conj (pop ranges) [s end])))) [[3 3]] [[1 2] [4 5]])
14:00clojurebot[[3 2] [4 5]]
14:01justin_smithjweiss: the init should be [[i i]] where i is the lower bound of the first range
14:01justin_smitheasy enough to set up in a function, of course
14:01jweissjustin_smith: i see
14:02jweissso i really want to conj the new range onto the sorted set, i thought the initializer was the item i'm adding
14:03justin_smithoh no, no, this reduce only does the combining, none of the sorting
14:03justin_smithI mean you could fix it to do the insertion, but that would be different
14:03jweisswouldn't i just call sorted-set at the end?
14:04justin_smithbut yeah, basically put the item into the sorted list or set of ranges, then do the reduce to combine apropriately
14:04jweissi see thanks
14:04justin_smithand maybe put back into a sorted set again when it's done even
14:05justin_smithsadly you can't peek or pop sorted-sets, if you could that would simplify the whole thing
14:06jweissright, will have to vec it and then turn it back to a sorted set. fortunately these lists will never be very long
14:06justin_smithwell, the reduce can use a sorted-set
14:06justin_smithsince they are at least seq-able
14:15jweiss,(reduce (fn [ranges [start end :as el]] (let [[s e] (peek ranges)] (if (> start e) (conj ranges el) (conj (pop ranges) [s end])))) [[1 1]] [[1 2] [3 3] [4 5]])
14:15clojurebot[[1 2] [3 3] [4 5]]
14:15jweissjustin_smith: i'm still missing something here
14:16justin_smithwhat's missing?
14:16jweissisn't that supposed to combine the ranges into [[1 5]]?
14:17justin_smithahh, then you need to chang (> start e) to (> start (inc e))
14:17justin_smithI think that should do it
14:17jweiss,(reduce (fn [ranges [start end :as el]] (let [[s e] (peek ranges)] (if (> start (inc e)) (conj ranges el) (conj (pop ranges) [s end])))) [[1 1]] [[1 2] [3 3] [4 5]])
14:17clojurebot[[1 5]]
14:17jweisssweet
14:57rhg136and remember kids, don't hold on to the head of a seq
15:17spuzi have a long running process that reads from a lazy sequence
15:17spuzis it possible to log or print whenever a new item is read from that sequence?
15:17dysfunno
15:18dysfunthere are ways to achieve a similar mechanism, but there is no automatic hook for reading
15:20spuzI was just looking for a way to adapt my existing lazy sequence
15:20spuzand I think this will work: http://stackoverflow.com/questions/24597228/how-to-observe-progress-while-consuming-a-lazy-sequence
15:34macroliciouswhy does (def x 0) (let [x (inc x)] x) => 1 ? I would think it would produce => 0
15:36dysfunbecause a local binding shadows a namespace binding
15:36dysfunit's why you can't write a function with a parameter 'list' and then use the 'list' function inside it without messing about
15:40rotcevis there a way to 'name' y and ys as a single parameter in clojure or do i just need to do (cons y ys) to join them where i need it [[x & [y & ys]]]
15:41dysfun [y & ys :as all-ys]
15:42rotcevty dysfun
15:42rhg135,(let [[a b :as c] [1 2 3]] [a b c])
15:42rhg135where did clojurebot go
15:43dysfunwell trust me, it works
15:43dysfuneven if clojurebot has gone off on one
15:45justin_smith,(let [[a b :as c] [1 2 3]] [a b c])
15:45justin_smithclojurebot: ?
15:45dysfuni thought we had a backup bot for emergencies like this?
15:45dysfunbut i cant remember what the magic incantation to invoke it is
15:46rhg135clojurebot was the backup afaik
15:46dysfunoh. right.
15:48macroliciousI can be the bot for now.
15:51macroliciousdj broken bot in the house
15:52rhg135this is tragic
15:53macrolicious=> Emilio Lizardo. Wasn't he on TV once?
16:12WorldsEndlessWhy doesn't this work? (-> "text" #(println %))
16:14justin_smithWorldsEndless: macroexpand-1 will tell you
16:14WorldsEndlessBut it doesn't....
16:14justin_smith,(macroexpand-1 '(-> "text" #(println %)))
16:14clojurebot(fn* "text" [p1__25#] (println p1__25#))
16:14justin_smiththat's what -> is doing
16:14WorldsEndless? Mine gives me a Runtime Exception
16:14WorldsEndlessoh, the quote
16:14justin_smithyou need to quote forms in order to macroexpand
16:14justin_smithyeah
16:15justin_smithso you see, #() expands to a call to fn, then "text" becomes the first arg to fn
16:15WorldsEndlesswhat's the p1_25# business?
16:15justin_smith,'#(foo)
16:15clojurebot(fn* [] (foo))
16:15justin_smith,'#(foo %)
16:15clojurebot(fn* [p1__74#] (foo p1__74#))
16:16justin_smithit's a random parameter name that won't clash with anything else
16:16justin_smith(in fact generated in a way that ensures it can't possibly clash)
16:17WorldsEndlessso, am I reading this right that "text" becomes the name of teh function, not a parameter?
16:17spuzwoot. i got my sudoku algorithm down from over an hour to under a second
16:18AimHereWas the hour one just brute force?
16:18spuzthey are both just brute force ;)
16:19WorldsEndlessspuz: added threading?
16:19spuznope
16:19spuzjust must simpler and smarter validity checking
16:19buttersI want to create a GUI app and am currently deciding on clojurescript and reagent. Is there something else that would be a better experience?
16:19spuzbefore I was creating a grid (vector of vectors) and then checking if that grid was valid
16:20spuznow I am simply picking a cell, and checking if the values 1-9 already exist in the rows/columns/squares that intersect it
16:20spuzi.e. no datastructure manipulation
16:21spuzactually, there is a bit of vector creation to get the columns and squares but somehow it's still pretty speedy
16:21WorldsEndlessbutters: I'm rather a fan of reagent/clojurescript
16:42spuzoh man, actually I found a really really stupid bug in my original implementation. I mixed up the x and the y coordinates which meant it was checking the wrong cells for validity
16:42spuzwith that fixed, the original solution is almost as fast as the new onw
16:44spuzi guess this is why we write tests
17:10xemdetiamaybe
17:13dysfunwhat's the go-to for reading edn in cljs?
17:15justin_smithdysfun: cljs.reader/read-string
17:16devthbest way to get a range of items in the middle of a lazy seq? repeatedly call nth?
17:16dysfunjustin_smith: ta
17:17amalloydevth: drop + take?
17:17devthamalloy: thx. it's a line seq. i wonder if nth would be any worse?
17:17amalloya lot worse, if i understand your question
17:18devthi don't know whether or not line-seq is indexed
17:18amalloyno
17:18amalloyand even if it were that wouldn't help
17:18devthgot it. ty
17:18justin_smithlazy-seqs are never indexed
17:18devthi guess that makes sense
17:20devthso every time you call nth it's iterating from the beginning, and forcing any unrealized values along the way
17:22justin_smithwell, "along the way" sounds open ended, but lazy seqs are always realized in order, but yeah
17:24phorseIs there a document anywhere that talks about project.clj? I'm getting confused about profiles vs builds and where dependencies belong and how you configure them.
17:24justin_smithphorse: lein help example
17:25justin_smithalso findable via google if you search for "leiningen sample project.clj"
17:25justin_smithphorse: oh, sorry, it's
17:25justin_smith"lein help sample"
17:26phorseWow, this is a gem!
17:26phorseThis should be more widely advertised, I think.
17:26justin_smithphorse: there are few things lein can do without a plugin that are not documented there
17:27phorseI might ask some more questions once I've read this, then, because I'm deep in the plugin weeds right now - mainly with figwheel but also with others.
17:28justin_smithplugins can do "anything" but typically either define a dev utility task launched by lein, or transform your deps somehow
17:33phorseSo, plugins can specify their own keys and configuration in the project.clj, right?
17:34justin_smithphorse: they can ingest the whole project file and it's up to them which part they use and how
17:34justin_smithyeah
17:34phorseAnd these can all be profile specific, as configured under the :profiles key?
17:34justin_smithright, or they can be top level keys in the profile
17:34justin_smithdepends on the plugin and how it is being used
17:35phorseOk, I think that makes sens.
17:36phorseDo you use environ? Do the keys in profiles.clj correspond with the profile ids in :profiles in project.clj?
17:37justin_smithyes and yes
17:37justin_smithwell wait, now
17:37justin_smithyes
17:37phorseok!
17:38justin_smithenviron lets me put less essential credentials for dev time in the project file, and prod configs in the env map on the server
17:38justin_smiths/less essential/less vulnerable/
17:38justin_smitheg. password to a server that doesn't even have access from the net
17:40phorseSo, in the case of a database connection, if I want to use one connection while in dev, but when I build an uberjar for prod use another database connection, I could specify that in the profiles.clj
17:41justin_smithwell, in prod you wouldn't have a profiles .clj would you?
17:41justin_smithin prod environ can read from an environment variable from the system
17:41phorseNo, but doesn't it merge the maps when uberjarring?
17:42justin_smithphorse: none of those profiles are available at deployment unless you seek them out and parse them by hand, they are build time / dev time config
17:42phorseAhh, I was confused then.
17:42justin_smithlein stuff is not for app config, it is for build config (but there is definitely a tendency to try to scope creep there...)
17:43justin_smithbut fundamentally it's a build tool
17:43justin_smithphorse: this is actually why environ is good - it can find a value in project.clj, in a java system property, or a shell environment variable, and your code will look the same
17:43justin_smithit just looks until it finds one
17:44phorseI'll have to play around with it - that could really simplify our process
17:44rhg135it's funny how short and simple the code is
17:45justin_smithrhg135: yeah, kind of hilarious actually - it takes more characters to explain how to use it and why it is useful than it takes to implement it
17:45rhg135indeed.
17:46rhg135like most of the seq functions without optimization
18:35WorldsEndlessI'm trying to specify the separator for a data.csv output to be a tab char, but it can't receive strings. How do I specify a tab char, since \t is a plain "t"?
18:39ToxicFrogWorldsEndless: \tab or \u0009
18:39ToxicFrogWorldsEndless: http://clojure.org/reference/reader#_literals
18:39WorldsEndlessAh! Thanks!
19:14justin_smith,(first "\tanother method")
19:14clojurebot\tab
19:16justin_smith,(iterate pr-str "\\")
19:16clojurebot("\\" "\"\\\\\"" "\"\\\"\\\\\\\\\\\"\"" "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\"\\\"\"" "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\"\\\"\"" ...)
19:17justin_smithwow, that blows up fast
19:17justin_smith,(drop 5 (iterate pr-str "\\"))
19:17clojurebot("\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\"\\\"\"" "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\...
19:19amalloyshould be exponential, right
19:19justin_smithyeah, I guess so
19:20justin_smith,(map count (iterate pr-str "\\"))
19:20clojurebot(1 4 10 22 46 ...)
19:20justin_smith,(map count (drop 5 (iterate pr-str "\\")))
19:20clojurebot(94 190 382 766 1534 ...)
19:26Glenjamin,(map count (drop 5 (iterate pr-str "\\\"")))
19:26clojurebot(126 254 510 1022 2046 ...)
19:27Glenjaminthat didn't have as much of an impact as i'd have hoped
19:27justin_smithpowers of 2 - 2 !
19:28justin_smithwhile mine is a little less clear
19:28Glenjaminexponential growth!
19:28Glenjaminyours is x2 + 2
19:29Glenjaminoh, they both are
19:29Glenjaminjust different start point
19:31justin_smithGlenjamin: yours is (2^n)-2, but I'm not seeing the formula for mine
19:32Glenjaminhrm, i need a repl
19:32Glenjaminor a spreadsheet
19:35justin_smith,(def n (map count (iterate pr-str "\\")))
19:35clojurebot#'sandbox/n
19:35justin_smith,(map - (rest n) n)
19:35clojurebot(3 6 12 24 48 ...)
19:35justin_smithso we have a series of doubled differences
19:35justin_smith,n
19:35clojurebot(1 4 10 22 46 ...)
19:36Glenjaminn1 = n0 * 2 + 2
19:36justin_smithyeah, sounds right
19:36Glenjamini've forgotten the maths to turn that into a function of i
20:33hxegonTrying to get node-host working with neovim for paraedit. Anyone know why I wouldn't have a bundle/node-host folder after :PluginInstall?
20:36hxegonnevermind... had a .vim folder and it was going off of that
20:48SomelauwIn Python I would create a startup file .pythonrc that contains lines like import re, import math, etc to have them immediately available when I start a repl. How would I achieve something similar in Clojure?
21:00rhg135The python repl is a lie! But AFAIK clojure does none of that magic
21:01rhg135Well, it will load user.clj on the classpath
21:24lockdownSomelauw: create an namespace with the ns macro and put what you need there, then in the repl switch to that nswith in-ns
21:34Somelauwlockdown: that's what I'm doing
21:52kenrestivois there any guarantee of the order that tests are run with clojure.test?
21:52kenrestivoreason being: i'm seeing on one machine, foo.bar-test is being run first, on another machine foo.baz-test is being run first
21:56rhg135I think the runner uses a map, but I may be wrong
22:01kenrestivothanks, that'd make sense. key order not guaranteed.
22:59cortexmanteach me something about clojure