#clojure logs

2015-12-11

00:07lambda-11235Is there any way to get that map from an exception?
00:12kenrestivothe only thing more ridiculous than java logging is java PKI management
00:14TEttingerkenrestivo: what about that restaurant in Japan that has monkey waitresses
00:14TEttingerI mean it's pretty ridiculous
00:25ridcullyi bet there is some relation
00:52devnlambda-11235: https://clojuredocs.org/clojure.core/ex-info
00:57devn,(ex-data (try (/ 1 0) (catch Exception e (ex-info "D'oh!" {:cause (.getMessage e) :other {:stuff "here"}}))))
00:57clojurebotdevn: Cool story bro.
00:57devn&(ex-data (try (/ 1 0) (catch Exception e (ex-info "D'oh!" {:cause (.getMessage e) :other {:stuff "here"}}))))
00:57devn,(ex-data (try (/ 1 0) (catch Exception e (ex-info "D'oh!" {:cause (.getMessage e) :other {:stuff "here"}}))))
00:57clojurebotdevn: Cool story bro.
00:58lambda-11235devn: I meant get the map from any exception like 1.7 print does, not just package data with an exception.
01:01lambda-11235ex-info is still cool, though I haven't seen it used often.
01:01devn,(try (/ 1 0) (catch Exception e (ex-info "D'oh!" {:cause (.getMessage e) :other {:stuff "here"}})))
01:01clojurebotdevn: Cool story bro.
01:02devnlambda-11235: run that in your REPL
01:02devnthat's exactly what you're looking for, i'm pretty sure
01:11lambda-11235devn: Not exactly. I had to look through the clojure source code, but I found it. It was Throwable->map.
03:17Trioxinwell, immutability seemed ridiculous to me at first but now I've got it and it's awesome.
03:19Trioxinnow, this notion of not entangling things sort of brings me to the Unix philosophy. Would that be a sufficient analogy?
03:30ridcullydo you mean the "do one thing and do it great"?
03:35Trioxinridcully, where hickley was talking about not entangling things within your software. I suppose not having objects and classes helps a lot with that but it sounded like he was also talking about programming practices within clojure, in some way having your functions and components not depend on the others so much. Maybe there's a good tutorial for the best ways to model your software in Clojure?
03:36TrioxinI'm coming from OOP so the last thing I want to do is incorrectly implement clojure based on what I'm used to.
03:43ridcullyi dont know one. same as the clojure universe don't has many "frameworks" and favours composition via libraries you do on your own, i'd expect only guidelines out there or "common wisdom"
03:43ridcullyand you most likely will end up doing things the wrong way - that's part of learning
03:45Trioxinridcully, so braveclojure isn't going to turn on all the light bulbs?
03:46ridcullyi can not comment on that. i have only read parts of the website some time ago
03:47Trioxinhmm. I'll come back when I've got it ALL down better via several tutorials.
03:47Trioxinwith those questions
03:48ridcullyi think some bulbs will light up by doing
03:48Trioxinthat too
03:49ridcullythere will be some moments when you jump off your chair with "yeah i did it" or "can't believe it's that easy"
03:51Trioxinwell I can see that happening and I can also see clojure beings so flexible as to be giving me plenty of rope to hang myself
03:52ridcullysure. there will be same amount of you jumping off your chair, pick it up, throw it out the window because that trillion line exception makes no sense at all ;)
06:13beakyehllo
06:26poweredhas development on Counterclockwise stopped or something?
06:55BRODUShow do i deconstruct a vector argument to a function such that i have the first value of the vector and the remainder of the vector as named values?
06:56luma(defn foo [[x & xs]] ... )
06:58BRODUSluma: thx
07:21marchelzowhat is the equivalent pattern in clojure to haskell's (c:cs)?
07:21ARM9clojure doesn't have pattern matching like haskell, but you can destructure a list/vector/string to a head and a rest with [x & xs] in most binding forms
07:22marchelzois 'match' just like ad-hoc pattern matching with macros?
07:23ARM9,(let [[x & xs] [1 2 3]] (cons x xs))
07:23clojurebot(1 2 3)
07:24ARM9what match?
07:24marchelzocore.match
07:24ARM9right, that's a library
07:24ARM9not actually part of the core language afaik
07:25marchelzoso if I wanted to write a function that handled two cases: the empty sequence, and [a & as], what is the idiomatic way to do that?
07:25ARM9yeah it's probably some macro soup
07:25ARM9with or without core.match?
07:25marchelzowithout
07:26MJB47what do you mean by empty sequence?
07:26MJB47as in no arguments to the function?
07:26ARM9an empty seq
07:26marchelzoI hope sequence is the right word
07:26marchelzomaybe I mean list
07:26ARM9(and (empty? []) (empty? "") (empty? '()))
07:26ARM9,(and (empty? []) (empty? "") (empty? '()))
07:26clojurebottrue
07:27ARM9no seq is probably what you want
07:27ARM9clojure abstracts several types of collections as sequences
07:27marchelzoand in the case that it isn't empty, I'd use 'let' to destructure it?
07:28ARM9(if-let [[x & xs] []] x)
07:28ARM9god I always forget the ,
07:34ARM9actually that might not be what you want, you might have to manually check the emptiness of the seq without something like core.match
07:36luma,(if-let [[x & xs] (seq [])] :match :no-match)
07:36clojurebot:no-match
07:38ARM9,(if-let [[x & xs] (seq [1 2 3])] (cons x xs) (iterate #(+ % 1) 1))
07:38clojurebot(1 2 3)
08:27douglarek, (identity "s")
08:27clojurebot"s"
09:13magtheI'm playing around with ring, and confusingly my :body attribute in requests has different type depending on if the request is sent using curl or from the browser... so question now is where do I read up on how to work with org.eclipse.jetty.server.HttpInputOverHTTP?
09:49justin_smithno matter what, it should implement InputStream, and you can use a ring middleware to pre-process, or slurp it to get a string if you want to process it yourself
10:58nanukodoes anyone have experience with quickie?
10:59vvgomesIs there any function to flip arguments of a function?
10:59poweredreverse
10:59vvgomeslet me try
11:00poweredsomething like (fn [f] (fn [& args] (apply f (reverse args))))
11:00justin_smith,(defn flip [f] (fn [& args] (apply f (reverse args))))
11:00clojurebot#'sandbox/flip
11:00justin_smith,((flip /) 3 2)
11:00clojurebot2/3
11:01poweredhaha, I thought of the same solution as an expect clojure user
11:01justin_smith,((flip map) (range) inc)
11:01clojurebot(1 2 3 4 5 ...)
11:02vvgomespowered: I don't think reverse does the job
11:03poweredvvgomes, look at the function justin_smith wrote earlier
11:03vvgomesyes, I could write that function... but I was looking for an existing one :/
11:04poweredthere's no core function that does that
11:04vvgomes:/ thanks anyway
11:04justin_smith,(defn shuffle-flip [f] (fn [& args] (apply f (shuffle args))))
11:04clojurebot#'sandbox/shuffle-flip
11:05justin_smithpretty-much-useless
11:05justin_smith,((shuffle-flip str) "pretty" "much" "useless")
11:05clojurebot"muchprettyuseless"
11:07maddagaskaHi, I'm trying to do something with code inspired by (copy-pasted from, mostly) less-awful-ssl but any time I try to use an SSLContext without a Key manager it gives me an exception: java.lang.IllegalArgumentException: array element type mismatch, compiling
11:07maddagaskaless-awful-ssl is here, and the highlighted line is the one I'm changing (to (.init nil) https://github.com/aphyr/less-awful-ssl/blob/master/src/less/awful/ssl.clj#L130
11:08vvgomespowered justin_smith I'm still trying to think of a point free version for that...
11:08powered'point free'?
11:08vvgomesyou know, without fn or defn
11:08justin_smith(comp (partial apply f) reverse list)
11:08vvgomeshttps://wiki.haskell.org/Pointfree
11:09vvgomesoh, let me try that..
11:09maddagaskaIs there anything obvious that I'm doing wrong?
11:09justin_smith((comp (partial apply /) reverse list) 3 2)
11:09justin_smith,((comp (partial apply /) reverse list) 3 2)
11:09clojurebot2/3
11:09justin_smithnot totally point-free - you need to get the function into the middle there
11:10poweredwhat's so cool about point free?
11:11justin_smithpowered: it's a cool mental exercise, in haskell it can avoid extraneous creation of new lambdas at runtime
11:11vvgomesplus, it makes function composition a lot easier
11:12poweredI never use function composition on higher level functions though
11:12justin_smithI mean it creates a function that takes the same args, and returns the same value... but maybe conceptually it makes the building blocks its made of easier to rearrange?
11:13BRODUSit makes clojure code more readable if youre using point free functions with '->>'
11:54TimMcmoar liek point less amirite
11:55winkI am confused. anyone got a hint? source: {:foo "f" :bar "b"} and what I need: [{:k :foo/"foo" :v "f} {:k :bar/"bar" :v "b"}]
11:56TimMcThat's an input/output pair?
11:56TimMcWhat is :foo/"foo", a weird keyword?
11:56winkI don't care if :foo or "foo"
11:57TimMcah
11:57TimMcmap over the map
11:57winkwhat I need: map to vec/list "of named tuples"
11:57TimMc,(for [pair {:foo "f" :bar "b"}] pair)
11:57clojurebot([:foo "f"] [:bar "b"])
11:58winkoh wow. thanks. that's what I get for never using for
11:58TimMcso instead of that last "pair" you can take apart the pair and make your :k :v map
11:58TimMc(for [[k v] ...] ...)
11:58TimMcalways use for :-)
11:59TimMcwink: But (map #(...) ...) would work just fine here.
11:59MJB47,(map (fn [[k v]] {:k k :v v}) {:foo "f" :bar "b"})
11:59clojurebot({:k :foo, :v "f"} {:k :bar, :v "b"})
11:59winkyup that's better
11:59winkthanks a lot!
11:59winkbrain too dead for this on a Friday night
12:00lumamapping an anonymous function is usually a sign that you should use for
12:01MJB47it is slightly shorter as for here
12:01MJB47,(for [[k v] {:foo "f" :bar "b"}] {:k k :v v})
12:01clojurebot({:k :foo, :v "f"} {:k :bar, :v "b"})
12:02MJB47which is more readable, up to you
12:03winkI like the for one more, but the other one makes more sense to understand why I failed
12:03winkif in doubt, destructure
12:09blischalkAnyone familiar with Quartzite know how to prevent a job from being triggered if there is already another job in progress?
12:15nickmbaileyit seems that 'lein uberjar' doesn't respect repositories configured in ~/.lein/profiles.clj, anyone run into that and know a fix?
12:25justin_smithnickmbailey: profiles.clj is not for things you want to have in your jar - it's for things you use locally but are not part of the codebase
12:26justin_smithif they belong in a project, explicitly add them to the project.clj
12:27nickmbaileywell the reason its in profiles.clj is because the repo has auth on it and i don't want to check that into git but fair enough
12:28nickmbaileyif i put the repository in the project.clj it will work?
12:28nickmbaileyjustin_smith: ^
12:28justin_smithyeah - I guess you need some mechanism for separating the auth from the jar though?
12:30nickmbaileywell you can set up repository credentials i guess but you have to like use gpg or something
12:30nickmbaileyits rather frustrating
12:32justin_smithright - but if you don't want creds in the repo, it seems just as bad to put them in the jar
12:33nickmbaileyi'm confused, why would they be in the jar?
12:33justin_smithproject.clj ends up in the jar
12:33nickmbaileyoh right
12:34nickmbaileyyeah i think i have to set up ~/.lein/credentials.clj.gpg
12:34nickmbaileyso that i define the repo url in project.clj but not the creds
12:34nickmbaileynot really sure if i understand why uberjar specifically ignores profiles.clj
12:35nickmbaileybut i'm probably just grumpy
12:35justin_smithnickmbailey: profiles.clj is for things you wouldn't put in a project - like dev utilities
12:36justin_smithit's not meant as "these jars belong in all my uberjars"
12:36nickmbaileywell uberjar is already smart enough to only pull in the deps of the project
12:37nickmbaileybut yeah ok
12:37nickmbaileyi wonder if I actually have to use gpg
12:37nickmbaileythats the annoying part
12:37justin_smithyou can put the creds in an env var
12:37justin_smithit depends on how important opsec is
12:38nickmbaileynot very, this is a temporary situation where i have to build from an internal repo
12:38justin_smithit's not like a var in your env is less secure than a file that is readable by any other user on your computer
12:38nickmbaileyand i have a team of 15 devs that i don't want to make go through some complicated process just to build the project
12:39justin_smithnickmbailey: I trained my team to use a creds.gpg - they ended up turning on the box OSX popped up "remember the password for this gpg keychain" and now I don't even know if they realize they are using gpg any more
12:40justin_smithwhenever they use our private repo, lein asks for the decrypt, gpg-agent talks to their osx keychain, and lein gets the decrypted data, with no interaction on their part
12:41nickmbaileyyeah but this has to build on jenkins which would be deb boxes, centos boxes, etc
12:41nickmbaileyi'm definitely grumpy
12:41justin_smithnickmbailey: that's where the env var option comes into play
12:41justin_smithon a machine where physical access is less of a risk, putting it in an env var is less of an issue
12:42nickmbaileyi suppose
12:42nickmbaileyat least most devs run osx
12:43nickmbaileyi guess the linux devs can handle figuring out gpg
12:43nickmbaileysigh
12:43justin_smithgpg-agent isn't much different under ubuntu (depending on desktop environment of course - if you want the smooth you are already using gnome, if you want the cranky devops way you aren't etc.)
12:48nickmbaileyjustin_smith: yeah
12:48nickmbaileythanks for the help btw :)
12:48nickmbaileydo you know what the env vars are off the top of your head
12:53nickmbaileyoh i see it in the help nvm
12:53nickmbaileyi am unsure how i mix the two though, if i put :creds :gpg in project.clj, then it won't look in the env on jenkins
13:12justin_smithnickmbailey: your local dev will be using the :dev profile, the uberjar process on jenkins will be using the :uberjar profile
13:18nickmbaileyah right, duh
13:18nickmbaileythanks
13:22nickmbaileyfiled a ticket to help make some of the creds error cases clearer fwiw
13:22nickmbaileyhttps://github.com/technomancy/leiningen/issues/2039
13:39nickmbailey(inc justin_smith)
13:40nickmbaileydidn't clojurebot used to respond to that?
13:42justin_smithlazybot did
13:42WorldsEndlessI heard that .cljc was supposed to be clojure -> C compiled, but I often see it seeming to mean "non-CLJS". Is there a standard?
13:43justin_smithWorldsEndless: .cljc allows multiple compiler targets in one file. It has nothing to do with C
13:44WorldsEndlessjustin_smith: ah... do you have an example of when .cljc would be better than .clj?
13:44justin_smithafaik it only does clj / cljs and maybe clr-clj
13:44WorldsEndlessOr how you can determine whether your file (with required libs) qualifies as cljc?
13:45justin_smithWorldsEndless: sure, when you want to have the same functions available in clj and cljs code. For example in my app we have a cljc lib for encoding and parsing a custom query parameter scheme that allows edn, we want to be able to create and parse the parameter strings from both the frontend and the backend
13:45WorldsEndlessSo does lein handle cljc differently, or is it just for developer semantics?
13:46justin_smiththe clojure compiler handles it differently
13:46justin_smithlein doesn't even need to know how it works, if you have a cljc file in classpath, clojure and clojurescript both know how to load it
13:48WorldsEndlessAh. That's cool
13:49WorldsEndlessI'm surprised not to have seen that mentioned in any of the various Clojure books
13:49WorldsEndlessAnd not easily findable by search engine, either
13:49postpunkjustinWorldsEndless: cljc is a pretty new thing, after (nearly?) all of the books came out
14:03WorldsEndlesspostpunkjustin: Thanks. Are you related to justin_smith ?
14:03postpunkjustinonly as co-Justins
14:04postpunkjustinand we attend the same Clojure meetup here in Portland
14:04justin_smithWorldsEndless: we've been seen in the same room multiple times
14:04postpunkjustinit's true
14:04WorldsEndlessJust making sure postpunkjustin is not referring to the name justin_smith :)
14:04postpunkjustinsorry for any confusion
14:05WorldsEndlessI am being tragically disabused of the notion that Clojure uberjar deployment would be a breeze...
14:05justin_smithWorldsEndless: but it is a breeze...
14:05WorldsEndlessI can "lein run" on both my local and AWS (identical codebase). I can "lein uberjar" and "java -jar new-jar" local. However, the same jar will NOT run on AWS, and I also can't "lein uberjar" on AWS.
14:06WorldsEndlessIt's driving me crazy.
14:06justin_smithWorldsEndless: my favorite trick is to aot compile nothing, and when running the uberjar launch clojure.main as the main class, telling it to require and run your primary ns
14:06justin_smithWorldsEndless: describe "will NOT run" in more detail?
14:07WorldsEndlessOn AWS: java -jar turbo-tenure.jar
14:07WorldsEndlessException in thread "main" java.lang.ExceptionInInitializerError
14:07justin_smithWorldsEndless: do you have a full stack trace somewhere?
14:07WorldsEndlessWhat's the simplest way to get around the "... 104 more" message and get a full trace?
14:07justin_smithmy first suspicion is java version, plus some compiled java deps that don't like that java version
14:08WorldsEndlessOk. that was my first suspicion also, because I haven't been able to get java 1.8 on SLES
14:08justin_smithwhat about 'java -cp turbo-tenure.jar clojure.main" then manually require your namespace?
14:08justin_smiththen you can use (pst) etc.
14:10justin_smith if you run clojure.main, all that needs is java 6
14:10WorldsEndlessjustin_smith: Clearly your java-fu is beyond mine. Do I need to write new code for that, or all from the CL?
14:10justin_smithWorldsEndless: that's a command line you can run
14:10justin_smithit gives you a clojure repl
14:11WorldsEndlessOh, cool
14:11justin_smithfrom that repl (require 'my-ns) (in-ns 'my-ns) etc.
14:11WorldsEndlessOk, that has helped me narrow things down
14:12WorldsEndlessMy suspicion is that it has to do with the environ module, which seems to break things when I try my app on new systems
14:12WorldsEndless<ec2-user> ~/ 18:58$ java -cp turbo-tenure.jar clojure.main
14:12WorldsEndlessClojure 1.7.0
14:12WorldsEndlessuser=> (require 'turbo-tenure.core)
14:12WorldsEndlessNullPointerException com.mongodb.ConnectionString.<init> (ConnectionString.java:195)
14:13WorldsEndless^^ was actually somewhere in the stack trace, too, but not as clear
14:13justin_smithcould this be because the required mongo connection info isn't being provided properly / isn't being found?
14:13WorldsEndlessThat's what I'm guessing, but I'm not sure why. The env vars are defined in project.clj, so should be available
14:14justin_smithWorldsEndless: java -jar ... is not governed by project.clj at all
14:15justin_smithproject.clj can set properties for dev time, when you are running lein, but does nothing when running your uberjar
14:15WorldsEndlessBut shouldn't it be reflected in the output of "lein uberjar"?
14:15justin_smithwhat would it output?
14:15justin_smiththere's no such mechanism for environ - you need to manually set those things for environ to work on prod
14:15WorldsEndlessMy project has the following under :profiles:
14:15WorldsEndless {:uberjar {:omit-source true
14:15WorldsEndless :env {:database-url "mongodb://127.0.0.1/turbo_tenure"
14:15WorldsEndless :production true}
14:16WorldsEndless
14:16justin_smithWorldsEndless: general assumption is that you would be using 12-factor style deployment, where you put the config in the environment vars
14:16justin_smithWorldsEndless: and the project.clj settings do nothing when running your uberjar
14:16justin_smithyou need to provide the credentials va the environment
14:16WorldsEndlessHmm... I thought they'd end up hard-coded in to the uberjar
14:16justin_smithor via java system properties you can set on the java command line if you prefer
14:17justin_smithWorldsEndless: nope, there's no such mechanism
14:17WorldsEndlessjustin_smith: Good to know
14:17WorldsEndlessspecifying extra "enviro" stuff assisted with dev on multiple systems, but cleary doesn't help with running your jar
14:25slesterwhat's the max length for a string? I seem to be stack overflowing
14:26justin_smithslester: the jvm does not store strings on the stack
14:26justin_smithslester: this is more likely happening in your code handling the string
14:26slesterhmmm!
14:26justin_smithit's one of the notorious java design decisions, putting nearly everything in the heap
14:26slesterjustin_smith, http://hastebin.com/xowanaqaho.lisp
14:27slesterit's for advent of code so...
14:27slesternot too much help :D
14:27slesterthe string gets really large
14:27MJB47you should refactor it
14:28MJB47to use loop recur
14:28MJB47at a minimum
14:28MJB47which implements TCO
14:28justin_smithslester: yeah, say calling say is likely what causes the SO
14:28justin_smithit should be as simple as changing "say" on line 11 to "recur"
14:28MJB47also you might want to use (seq input) instead of /split
14:28slesteroh, I see
14:28slesterI don't quite understand the difference between recur & calling the function
14:29MJB47recur uses some magic
14:29MJB47to not blow the stack
14:29justin_smithslester: calling the function uses more stack
14:29justin_smithslester: recur is basically just a loop, no extra stack usage
14:29slesterooh, well it seems to be working! or going further anyway.
14:30slesterthanks for that tip
14:30MJB47you could have also used doseq for this
14:30justin_smithMJB47's idea for using seq / chars instead of split / one letter strings is a good one too
15:18fsjhfkjdhfhi why can't i sort a list by type? (sort-by type [1 :a 2 :b 3 :c])
15:18fsjhfkjdhfi get the error: java.lang.ClassCastException: null
15:19amalloy(doc sort-by
15:19amalloy(doc sort-by)
15:19clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:19clojurebot"([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator. If coll is a Java array, it will be modified. To avoid this, sort a copy of the array."
15:19amalloy,((sort-by type [1 :a 2 :b 3 :c]))
15:19clojurebot#error {\n :cause "java.lang.Class cannot be cast to java.lang.Comparable"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Class cannot be cast to java.lang.Comparable"\n :at [clojure.lang.Util compare "Util.java" 153]}]\n :trace\n [[clojure.lang.Util compare "Util.java" 153]\n [clojure.core$compare invokeStatic "core.clj" 808]\n [clojure.core$compare invoke "core.clj" -1...
15:20fsjhfkjdhflol see what i mean
15:21justin_smith,(compare String Character)
15:21clojurebot#error {\n :cause "java.lang.Class cannot be cast to java.lang.Comparable"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Class cannot be cast to java.lang.Comparable"\n :at [clojure.lang.Util compare "Util.java" 153]}]\n :trace\n [[clojure.lang.Util compare "Util.java" 153]\n [sandbox$eval93 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval93 invoke "NO_SOURCE_FILE" -1]\...
15:21justin_smiththat's the error
15:21justin_smith,(sort-by (comp str type) [1 :a 2 :b 3 :c []])
15:21clojurebot(:a :b :c [] 1 ...)
15:21justin_smithas long as every type prints uniquely that should be good enough?
15:22fsjhfkjdhfhooray thank you!
15:22fsjhfkjdhf(trying to solve 4clojure problem 50 ;))
15:23justin_smithfsjhfkjdhf: in case it's not clear, that's getting each type, then converting to string, since you can compare and sort strings (unlike classes)
15:24fsjhfkjdhfyeah it makes sense thank you :D
15:25fsjhfkjdhfhooray beat 50
15:26fsjhfkjdhfoh whoops
15:26fsjhfkjdhfgroup-by == sort and then partition by.. oh well
15:27justin_smithfsjhfkjdhf: my solution to that one - (comp vals (partial group-by type))
15:27fsjhfkjdhfyeah i see that
15:27fsjhfkjdhfi used #(partition-by (comp str type) (sort-by (comp str type) %))
15:28justin_smithfsjhfkjdhf: the partition-by can still use type
15:28justin_smithit's only the sort that needs (comp str type)
15:28fsjhfkjdhfoh right yeah
15:28justin_smithsince partition-by only needs to compare = or not
15:28fsjhfkjdhfmmhm
15:29justin_smithfsjhfkjdhf: so you got double the learning experience on one puzzle by finding two approaches
15:29fsjhfkjdhfhaha yeah that seems to be the case with almost all of them
15:29fsjhfkjdhf"finally got it working and ... oh it can be solved with this one function"
15:30justin_smithfsjhfkjdhf: reduce never made sense to me until I made my own crappy version
15:30justin_smithand then I was like - oh wait, that's what reduce is for? it makes sense now!
15:30fsjhfkjdhfyeah i'm still a bit unsure about reduce so i try to use it for a lot of solutions so i can practice it
15:30justin_smithfsjhfkjdhf: I even made my own silly message passing / data flow system before I groked core.async
15:30fsjhfkjdhfhehe
15:31justin_smithmaking the bad version is one way to learn how the good version works
15:32justin_smithfsjhfkjdhf: the big game changers with reduce are: reduced - return this value immediately skipping the other input, and the fact that you can pass a data structure as your accumulator in order to effectively have multiple accumulators
15:32fsjhfkjdhfyeah it seems like just about anything can be done with reduce
15:32fsjhfkjdhfsince it maintains state between operations
15:32justin_smithas long as your input is a collection, sure
15:33justin_smithreduce is what many people expect for to be (based on what for is in C / java)
15:34justin_smithfsjhfkjdhf: but it does something better than maintaining state - it allows the explicit propagation of state, rather than implicit state mutation :)
15:35fsjhfkjdhfyeah so you can have state and purity too pretty cool
15:35fsjhfkjdhfomg finally i passed my friend
15:35fsjhfkjdhfme and two other people are learning clojure and racing to the end of this 4clojure website
15:36justin_smithhah, nice, I still haven't done all the problems there
15:36fsjhfkjdhfwhat number are you on?
15:36justin_smithhmm...
15:37oneif i have a function that uses variadic overloads can i also include keyword arguments?
15:37onei keep getting errors
15:37oneCan't have more than 1 variadic overload
15:37__iori'm also working throuh 4clojure, it's pretty great, though i wish questions that came after "not allowed to use core.somefunction" actually required core.thefunctionyoujustrewrote
15:38justin_smithfsjhfkjdhf: rank 344, 140 problems solved, user name "noisesmith"
15:38__iorthat way you could really get the feel for the core libraries
15:38fsjhfkjdhf! quite a bit
15:39justin_smiththe 16 I have left are tough ones though
15:40oneno?
15:40clojurebotno is tufflax: there was a question somewhere in there, the answer
15:41justin_smithone: a function can't have more than 1 variadic overload- how would clojure know which one of them to call?
15:43oneis there any way to force keyword arguments then?
15:43onewith overloads
15:44onebecause the alternative is making like 30 changes to everything that calls this fucntion
15:45oneis there a way to assign default values to & [x y z]?
15:45onebecause that would work too
15:45onepossible
15:45onepossibly
15:45ARM9((fn[& {:keys [a b c]}] [a b c]) :a 1 :b 2 :c 3)
15:45ARM9,((fn[& {:keys [a b c]}] [a b c]) :a 1 :b 2 :c 3) ; for posterity
15:46clojurebot[1 2 3]
15:46onebut i need the non keyword arguments to have defaults
15:46oneas well as the keyword arguments
15:46ARM9you can set keyword arguments to defaults at least, not sure about other arguments
15:46oneyea
15:47onethe way its done in the code is basically
15:47ARM9,((fn[& {:keys [a b c] :or {c 42}}] [a b c]) :a 1 :b 2)
15:47clojurebot[1 2 42]
15:48one(defn x ([a] (x a 0)) ([x y]))
15:48onebut far larger
15:50justin_smithone: clojure.core makes separate arities for everything up to 4 args or so typically, then finally implements varargs after that
15:50justin_smithnot that the way clojure.core does it is always best I guess
15:52onei see
15:52onei didnt write any of this code, im just trying to hack some functionality into it
15:52onenever worked with clojure before
15:52justin_smithwelcome!
15:53onethe guy who wrote it claims that clojure is the best language in the world
15:53one:p
15:53onei think its excessive for an api tho
15:56onecan i do something like
15:56oneargs :as x and then do kwargs
15:56justin_smithabsolutely
15:57oneand then have some logic to assign defailts to the values i x?
15:57onei think thats the best way
15:58onei guess have to count the len of args
15:59justin_smith,((fn [& [a b c :as args]] (let [defaults [1 2 3] bindings (map #(or % %2) args defaults) [a b c] bindings] [a b c]) 42 43)
15:59clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:59justin_smitherr
16:00oneah
16:00onenice
16:00one:p
16:01onebtw, is it improper to end functions with ))))]}))]) and not use ANY indentation at all?
16:01justin_smithyes
16:01justin_smitherr
16:01onemakes it hard to read tho
16:01justin_smithno, not improper, that's the right way to do it, we don't do hanging delimiters
16:02onei see
16:02oneits very confusing trying to read that in vim :p
16:02ridcullyuse paredit
16:02justin_smiththere is surely a better way to do this:
16:02justin_smith,(fn [& [a b c :as args]] (let [defaults [1 2 3] bindings (map #(or % %2) (concat args (repeat nil)) defaults) [a b c] bindings] bindings)) 42 43)
16:02clojurebot#object[sandbox$eval51$fn__53 0x45c7be7 "sandbox$eval51$fn__53@45c7be7"]
16:02justin_smith,((fn [& [a b c :as args]] (let [defaults [1 2 3] bindings (map #(or % %2) (concat args (repeat nil)) defaults) [a b c] bindings] bindings)) 42 43)
16:02clojurebot(42 43 3)
16:04justin_smithone: typically we don't read the parens - we use something like paredit that makes sure the parens are good (or even just auto-indent and fixing anything that indents funky)
16:05onei see
16:05onethat makes sense
16:05justin_smithsee also rainbow-delimiters that makes non-matching ones an ugly color
16:05ridcullyparedit made me stop worrying. cljformat cleans up after me
16:05justin_smithyeah, cljformat looks like a game changer
16:06ridcullyadd the vim-sexpr-something-them-name-i-forgot and you are good to go
16:06justin_smithyeah, vim definitely has some decent tools for working with lisp
16:07justin_smithI use emacs with evil mode turned on myself, but am seriously considering trying vim again since I already use most of hte keybindings
16:17postpunkjustinspacemacs
16:19lxsameerhey people, I have a json api and I need a background job and an scheduler , what do you suggest?
16:20justin_smithlxsameer: java.util.concurrent.ScheduledThreadPoolExecutor
16:20justin_smithit's not a hard api, and it's got all the right features for scheduling periodic tasks
16:20lxsameerjustin_smith: thanks man
16:21postpunkjustinlxsameer: there's also overtone/at-at, which you may find more convenient
16:21justin_smithpostpunkjustin: eh, it's a thin wrapper to what I just suggested :P
16:22lxsameercool
16:23michael_tetersomething strange has happened. I haven't used emacs in a couple of weeks, and now it fails on start with one after another error from my init
16:24michael_teterI've been pulling out things, and by now I think there's some root problem that's causing everything to fail
16:24michael_tetermaybe it's a hint that I should learn Cursive :/
16:24justin_smithmichael_teter: try deleting your .elc files - it could be that a melpa update broke some things with your older installed libs
16:24justin_smithor use cursive, cursive looks cool
16:25michael_teterit does, but it's yet another learning curve :). I will, but damnit I finally came to love Emacs. It's just that Cursive's debugger is so sexy
16:25michael_teterthanks, I'll try
16:25justin_smithpostpunkjustin: perhaps I am too grumpy about the thin wrappers - it just seems like we'd all be better off doing the interop but maybe that's idealistic
16:25postpunkjustineh, it's a matter of taste
16:29justin_smithpostpunkjustin: for example, ther other day in order to do something with an explicitly provided timezone (and not just a fixed numeric offset from GMT) I had to chase the docs from clj-time to joda-time to java.util where I finally found the method I needed
16:29postpunkjustinyeah, stuff like that is definitely frustrating
16:29justin_smithwrappers!
16:31ridcullywhat they are good for?
16:31justin_smithbut this means I'm only a few steps removed from that grouchy assembler programmer who thinks c is just a bunch of lossy abstractions that waste your time, heh
16:31postpunkjustinyou'll get there someday, no need to rush it
16:42amalloyjustin_smith: reminds me of https://ro-che.info/ccc/20
16:45justin_smithhaha
17:10oneicant figure out how tp pass both args and kwargs
17:10justin_smithone: kwargs have to come after the args
17:10ridcullyand i thought i was in #python
17:10justin_smithone: also, it's nice to use a hash-map with the args instead of kwargs if that's an option
17:10oneif i do & [x y z :as args {:keys [d e f]}]
17:11justin_smithone your args and kwargs can't both be optional
17:11oneis that the proper syntax?
17:11justin_smithno, because you can't have both optional args and kwargs
17:11onetheres no way to force that behaviour?
17:15WorldsEndlessI'm using CAS in my web app, which requires a return address for after the CAS handshake occurs. Anyone know a quick and easy way (maybe Ring or Compojure) to grab my app's current address, rather than hardcoding something that will break in the change from dev to production?
17:16justin_smithWorldsEndless: usually I use a config map for this - a mapping like {:dev "localhost" :staging "staging.example.com" :prod "example.com"}
17:17justin_smithand then use the env to set on of :dev / :staging / :prod
17:17WorldsEndlessThat sound smart
17:17justin_smithWorldsEndless: it's worked for me
17:18justin_smithI end up having a bunch of maps like that
17:18WorldsEndlessout of curiosity, do you actually in the env do `export site=:dev' or does the :key need to be inserted else-ways?
17:18justin_smithfor db ports / db hosts, api accounts to connect to, etc.
17:19WorldsEndlessYeah, I'm catching on to this 12-step thing. That makes sense
17:19justin_smithWorldsEndless: I put it in the java startup "SITE=dev java -cp my-uber.jar clojure.main my-main-class"
17:19postpunkjustinI think the 12-step thing is slightly different...
17:19postpunkjustinbut hey, maybe not
17:20justin_smithpostpunkjustin: it probably is, I am not doing 12-step to the letter
17:20WorldsEndlesspostpunkjustin: One of the emphasis I noticed (having watched the YouTube video, I'm now a pro) is taking care of your env. vars
17:20postpunkjustinI mean, do what works and take it one day at a time I guess.
17:21justin_smithpostpunkjustin: so the 12 step way would be to have an environment config file that is sourced by my shell instead of putting it on the command line, right?
17:21WorldsEndlessjustin_smith: that's what I understood
17:21justin_smitherr, 12 factor, oops
17:21WorldsEndlesslol
17:21WorldsEndlessI just did a double-take on that
17:22justin_smithI'm justin_smith, and I do dev ops. It's been 3 days since the last deploy disaster.
17:22justin_smithhaha
17:22WorldsEndlesslol
17:22WorldsEndlessMy first LOL with my current office neighbors...
17:23WorldsEndlessIn the 12-factor paradigm, Docker's handling of containers (with massive env setups) makes more sense
17:23ridcullyi am disappointed. you seemed like the noops guy
17:24justin_smithheh
17:24justin_smithridcully: I am actually not the main devops guy at my company, but that just fit the convo flow here...
17:25ridcullygotta do
17:25justin_smithI'm mainly the guy that talks about clojure on irc while occasionally implementing a feature or unit test for the product
17:25ridcullysame here... if ya don't do it, it won't fix itself
17:28ridcullywhat are those? pragmaticops? fixops?
17:28ridcullynavysealops?
17:49nanukois there any way to repl into a clojure standalone jar as it’s executing?
17:51justin_smithnanuko: you can explicitly run a repl from your -main via nrepl if you add it as a dep, or you can use "java -cp your-uber.jar" to start up the process, and manually start -main in a separate thread
17:51justin_smithprobably in screen or tmux or something for it to be really useful
17:52nanukoah, that makes sense. but that wouldn’t work for something like heroku, correct?
17:53justin_smithyeah, on heroku nrepl is likely easier (then you can ssh tunnel to the port, and use lein repl :connect locally)
17:53justin_smithyou can still ssh into the heroku machine once it is up, right?
17:58nanukoyup
17:59nanukoyou would still have to call something like this (defonce server (start-server :port 7888)) in your app
17:59nanukoi think
18:02fsjhfkjdhfhey justin_smith you there? got another question :D
18:03fsjhfkjdhfor for anyone really: i'm wondering why this is just returning a function without any output: (defn myfunc [xs] (keep-indexed (fn [idx v] (if (= (dec v) (nth xs (max 0 (dec idx)))) v))))
18:04fsjhfkjdhfi'm trying to get a list with only elements that are one larger than the one before them
18:06amalloyyou never use xs
18:08oneSUCESS
18:08fsjhfkjdhfamalloy: yeah i do? right after nth
18:08amalloy(defn myfunc [xs] (keep-indexed (fn ...)))
18:09fsjhfkjdhfah
18:09fsjhfkjdhfok changed that and it's still not giving me anything
18:09fsjhfkjdhf(defn myfunc [xs] (keep-indexed (fn [idx v] (if (= (dec v) (nth xs (max 0 (dec idx)))) v)) xs))
18:09amalloy,(defn myfunc [xs] (keep-indexed (fn [idx v] (if (= (dec v) (nth xs (max 0 (dec idx)))) v)) xs))
18:09clojurebot#'sandbox/myfunc
18:10amalloy,(myfunc [1 2 4 5])
18:10clojurebot(2 5)
18:10amalloyLGTM
18:10fsjhfkjdhfohhhh my repl was broken
18:32WorldsEndlessAnyone bumpted into SLF4J "multiple binding" errors before? Apparently two of my dependencies use conflicting versions of SLF4j
18:32WorldsEndlessBut I'm not sure which ones they are..
18:33justin_smithWorldsEndless: SLF4j defines an interface, and iirc this issue is that you have two different libs that are available that implement the interface - usually this means it just ends up picking one and warning you that two both were available
18:34justin_smith"The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time."
18:35justin_smithhttp://www.slf4j.org/ - so the conflict isn't two versions of one lib, it's two libs that both want to provide a dep for slf4j, and slf4j feels that it is underconfigured
18:35WorldsEndlessYeah, it tells me the repos are ch.qos.logback.logback-classic, and org.slf4j, but neither of those are really ringing a bell
18:35justin_smithWorldsEndless: "lein deps :tree" will show you who pulls each of those in, then you can exclude one
18:35WorldsEndlessAh! That's the command I needed. Thanks.
18:36justin_smithslf4j itself will not provide a logger, iirc - it needs one of the other libs
18:38WorldsEndlessWhoa. It has lots of "consider these exclusions" lines
18:38WorldsEndlessfar more than just slf4j
18:38WorldsEndlesslike,
18:38WorldsEndlessConsider using these exclusions:
18:38WorldsEndless[lein-figwheel "0.5.0-2" :exclusions [org.clojure/clojure]]
18:38WorldsEndless
18:38WorldsEndlesswhich seems strange to me
18:41WorldsEndlessHe rowed away...
18:44ridcullyno he did'nt
18:44WorldsEndlessStrange that things that bring in newer versions get overridden by things using older versions
18:44WorldsEndlessOr maybe that's by design.
18:54fsjhfkjdhfanyone know why this isn't working? (defn subsequences [xs] (reduce (fn [acc v] (if (= (dec v) (last (last acc))) (conj (last acc) v) (conj (last acc) [v]))) [] xs))
18:54fsjhfkjdhftrying to get a vector of subsequence vectors..
18:54fsjhfkjdhfkeep getting error: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long
18:59justin_smithfsjhfkjdhf: why (last (last acc)) ?
18:59fsjhfkjdhfhi justin!
18:59fsjhfkjdhfuhmmm let's see
18:59justin_smithfor that to work, you should use a different init
18:59justin_smith(I think)
19:00fsjhfkjdhfwell i want to add it to the embedded vector if it's a part of the same sequence
19:00fsjhfkjdhfotherwise i want to create a new vector
19:00fsjhfkjdhfthe first test should always fail
19:00fsjhfkjdhfbecause it will be comparing a number to an empty vector
19:00fsjhfkjdhfand that will create a new vector
19:01fsjhfkjdhfoh wait
19:01fsjhfkjdhfi think i see a problem
19:01justin_smithfsjhfkjdhf: the error is (conj (last acc) v)
19:02fsjhfkjdhfreally
19:02fsjhfkjdhfhmm
19:02justin_smithreplace that with (conj (pop acc) (conj (last acc) v))
19:02justin_smithotherwise you lose most of the acc - and it has the wrong shape next time through
19:03justin_smithand then you get the error next time thorugh - it is a vector of numbers instead of a vector of vector of numbers
19:03justin_smithremember that what you return from the fn is the entirety of acc next time
19:03fsjhfkjdhfoh right..
19:03fsjhfkjdhfhmm this is harder than i initially hoped for lol
19:03justin_smithso really both your branches of that if need to use pop acc ass above
19:04justin_smithalso, you can use peek instead of last for style / efficiency points
19:05slesterif I want to take certain letters out of (def abcs (map char (range (int \a) (inc (int \z))))), how do I do that exactly? :(
19:05justin_smith(if (= (dec v) (peek (peek acc))) (conj (pop acc) (conj (peek acc) v)) (conj acc [v]))
19:05slesterlike I want to remove '((int \c) (int \d))
19:06justin_smith(remove #{\c \d} abcs)
19:06justin_smith,(remove #{\c \d} map char (range (int \a) (inc (int \z)))))
19:07clojurebot#error {\n :cause "Wrong number of args (4) passed to: core/remove"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (4) passed to: core/remove"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 44]\n [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval2...
19:07justin_smithoops
19:07justin_smith,(remove #{\c \d} (map char (range (int \a) (inc (int \z)))))
19:07clojurebot(\a \b \e \f \g ...)
19:07slesterwhat is #{} doing there exactly?
19:08justin_smith,(map #{1 2} (range))
19:08clojurebot(nil 1 2 nil nil ...)
19:08justin_smithdoes that help?
19:08justin_smith,(#{:foo :bar} :foo)
19:08clojurebot:foo
19:08justin_smith,(#{:foo :bar} :baz)
19:08clojurebotnil
19:08slesterthat's really hard to google for, what's it called?
19:09justin_smith,(type #{})
19:09clojurebotclojure.lang.PersistentHashSet
19:09slesternot really, but I'm not very smart
19:09slesterthanks
19:09justin_smithslester: when you use a set as a function, it returns the arg, if the arg is in the set
19:09justin_smithothwerwise it returns a default, and the default default is nil
19:10slesteroh I see, so remove applies the pred to the list, and they all return nil unless they're in the set
19:10justin_smithright
19:10justin_smithand if the f for remove returns nil, the item is not removed
19:10justin_smithbasically, a set can be used as a way to test if a value belongs to some set of values you are interested in
19:12slesterjustin_smith: thanks, you're a lifesaver (or at least a time- and brain-saver)
19:13justin_smithheh, I try
19:13slesteralways nice to have nice helpful gurus about, makes me much more likely to keep pounding my head against clojure until it sticks
19:14justin_smithman, if I was a guru I could talk people into giving me their life savings, or I could levitate maybe... something
19:14slesterhaha
19:14slesterisn't creating something out of nothing guru-esque?
19:15slesterprogramming hurray
19:17justin_smithfair
19:49didibusI've got a function that takes a vararg and some other args. How can I call tha function, give it the normal arg, and pass a map to it as the vararg?
19:49didibusI know apply would work if it only takes a vararg
19:50didibusoh, nevermind, apply does work in this case too
20:04alive876hi, could any one tell me when i run lein on a project it comes back with xx is not a task ? thanks in advance!
20:21tolstoyalive876: The second param to lein is a task. "lein run" "lein test" and so on. If you specify a task that doesn't exist, you get that message.
20:24alive876ok thanks
21:24irctcHi everyone. :)
21:25irctcIs there a way to select only parts of XML between two nodes so that I could parse just that part from an XML document instead of the entire thing?
21:27irctcFor example I'd jiust like to parse the stuff between the <bar></bar> nodes but my document looks like <foo><boo><bar><element></element></bar></boo></foo>
21:29tolstoySeems like you could 1) do some regex on the string, or 2) just parse it, pull out the node you want and throw the rest away.
21:30tolstoyclojure.xml/parse turns XML to clojure data. From there, you could find the right place.
21:30irctcI am already doing it the second way.
21:31irctcI don't know regex and am a bit scared of working with it. It just looks weird lol
21:31tolstoyAre you worried about the size of the XML or something?
21:31irctcWell it's the performance hit that my app takes and I'd just like to process a smaller part of it.
21:32irctcFrom performing functions at 1msec it goes all the way up to about a 1000 msecs and I'd like to lower that as much as possible.
21:33tolstoyThis claims to be lazy: https://github.com/clojure/data.xml. Perhaps that fits?
21:33irctcThat's when it has to parse the xml file. Because I don't need the entire file parsed I thought I'd just cut it down from the get go.
21:34tolstoyMaybe the "lazy" version doesn't parse the whole thing, so you only have to worry about every in front of "<bar/>".
21:35irctcAnd clojure.xml isn't lazy?
21:35tolstoyHm. Read in the string, split on "<", then (drop-while not= "<bar", then take-while (not= "</bar") and join the string up again and parse?
21:36tolstoyclojure.xml/parse doesn't mention the word lazy, so I assume not.
21:36irctcHmmmm, that might actually work. I'll test to see how much time it takes to process the file before I parse it.
21:37tolstoyAnyway, I think the reason data.xml exists is to provide that lazyiness.
21:37tolstoyYeah. How fast is string/split? Etc.
21:38irctcThanks tolstoy. Btw, Tolstoy is one of my favorite authors. Don't know if you chose that nickname because of him, it just reminded me of him. :)
21:38tolstoyIn Emacs, I used to load up a message XML file, then string-replace >< with >\n< and then select-all, then hit tab. Cleans it right up!
21:39irctcThat's a neat solution and I thought of doing that but the elements before the elements that I actually need vary in length so I can't rely on that.
21:39tolstoyMy fave is Chekhov, actually.
21:41tolstoyIs the file already broken into lines?
21:41irctcI don't know what that means.
21:42tolstoyAre there carriage returns in the XML file already, or is it just one big long string.
21:42tolstoyI know you've read it in as a big string, but maybe there are "\n" in it.
21:42tolstoySplit on those, then compare strings.
21:43irctcNah, just a big long string.
21:44tolstoyHow much do you know about XML processing? Like, DOM vs SAX and so on?
21:45irctcOh, not that much.
21:45irctcDid some basic DOM navigation but that's about it.
21:45tolstoyWith DOM, you load the whole thing in, then you can do Xpath with it.
21:46tolstoyWith SAX, you register a handler which is notified of each node as you go along.
21:46irctcI'm actually thinking of doing this to replace multiple strings with /n: http://stackoverflow.com/questions/9568050/in-clojure-how-to-write-a-function-that-applies-several-string-replacements
21:47tolstoySo, you could just "if the node doesn't equal bar, don't do anything", but I don't think you can say, "Here's bar, now return the entire sub-tree."
21:48tolstoyHm. You could (s/split xml #"<bar|</bar") maybe.
21:49irctcLet me try that. That sounds nice.
21:50tolstoy,(clojure.string/split "<foo><bar><baz>hello</baz></bar></foo>" #"<baz>|</baz>")
21:50clojurebot["<foo><bar>" "hello" "</bar></foo>"]
21:51tolstoy,(str "<baz>" (second (clojure.string/split "<foo><bar><baz>hello</baz></bar></foo>" #"<baz>|</baz>")) "</baz>")
21:51clojurebot"<baz>hello</baz>"
21:52irctcHow would I select just the "hello" from that vector if I don't know where it's going to be because the nesting hierarchy varies?
21:52tolstoyThe assuming is that there's just one <baz> element in the whole doc.
21:53tolstoys/assuming/assumption/
21:53irctc(second (clojure.string/split "<foo><bar><baz>hello</baz></bar></foo>" #"<bar>|</bar>"))
21:53irctc,(second (clojure.string/split "<foo><bar><baz>hello</baz></bar></foo>" #"<bar>|</bar>"))
21:53clojurebot"<baz>hello</baz>"
21:54irctcSometimes there are multiple.
21:54tolstoyI think "split" takes a max number of values to return.
21:56tolstoySo, some sort of loop/recur where you (loop [xml xml] (let [[_ bar rest] (split xml #"<bar>|</bar>" 3) (process bar) (recur rest)) ) or something like that.
21:56irctc,(second (clojure.string/split "<foo><bar><baz>hello</baz><baz>hello</baz><baz>hello</baz></bar></foo>" #"<bar>|</bar>" 2))
21:56clojurebot"<baz>hello</baz><baz>hello</baz><baz>hello</baz></bar></foo>"
21:56irctc,(clojure.string/split "<foo><bar><baz>hello</baz><baz>hello</baz><baz>hello</baz></bar></foo>" #"<bar>|</bar>" 2)
21:56clojurebot["<foo>" "<baz>hello</baz><baz>hello</baz><baz>hello</baz></bar></foo>"]
21:57irctcOk, so it stops splitting at the limit.
21:57irctcBut returns the last element unprocessed.
21:58tolstoyRight. Then you take that unprocess element, and try again. Keep going until there's none left.
21:58tolstoyYou could do it in a recursive function that just gathers up the "good" parts and returns them.
22:02tolstoyirctc: Something like this? https://gist.github.com/zentrope/9d09c91deab0351421e5 (untested).
22:07tolstoyOy, that's bad code.
22:09tolstoyOkay, this works: https://gist.github.com/zentrope/9d09c91deab0351421e5
22:10tolstoyCould make a version that uses lazy-seq, but I'd have to remember how. ;)
22:11irctcThat's a cool solution. :) Thanks! :)
22:13justin_smithirctc: see also clj-tagsoup if you know the tag that will contain your content, but not the structure
22:13justin_smithit has a lazy version too
22:13justin_smithhttps://github.com/nathell/clj-tagsoup
22:17irctcThanks justin_smith. :)
22:19noobie_any idea why this wouldn't work? (read-stdin) is defined as (defn read-stdin [] (line-seq (java.io.BufferedReader. *in*)))
22:20noobie_http://sprunge.us/JLGK
22:20noobie_something about not being able to use nth
22:21tolstoyirctc: Well, added a lazy-seq version. I think.
22:21justin_smithnoobie_: looks like it works to me https://www.refheap.com/112613
22:22justin_smithnoobie_: perhaps you are trying to use it in the repl, and the repl already wants to own *in* ?
22:22justin_smithor perhaps nothing is consuming the lazy-seq
22:24justin_smithnoobie_: common/read-stdin is a function, not a function call
22:24irctcThanks tolstoy. :)
22:24justin_smithnoobie_: sorry about my above, I had not seen your paste
22:24justin_smithnoobie_: if you replace common/read-stdin (a function) with (common/read-stdin) (a call to that function) it should print your first line
22:24tolstoyirctc: Heh. The addition to that post actually works. If you add printlns and then (take 1 ...) from each method, the get-bars function parses the whole thing before returning the first element, while lazy-seq version only does the first. Ugly, but it works-ish.
22:25noobie_justin_smith: ahh, yes
22:25noobie_justin_smith: do i require doseq instead of let?
22:25noobie_let seems to act weird with a line-seq
22:25tolstoyirctc: I guess that's useful if you're worried about memory.
22:25justin_smithnoobie_: if you replace if-not with when-not, it would even recur and consume more than one non-nil line
22:25justin_smithnoobie_: it's not let that is misbehaving I bet
22:26justin_smithnoobie_: what do you expect to happen - do you expect more than one line to be printed?
22:26noobie_i expect them to be print as i type them
22:26noobie_right after i hit enter
22:26justin_smithnoobie_: your if-not ensures that it only recurs if the line is nil
22:26justin_smithyou want it to recur for every line until one of them is nil
22:27justin_smithnoobie_: maybe you mean when-not rather than if-not
22:27noobie_hmm yeah
22:27justin_smithnoobie_: the reason I used doseq is I had not seen your code yet, and doseq is the normal way to perform some side effect for each item in a sequence
22:27justin_smithnoobie_: you can do the same thing with loop, but doseq makes it simpler
22:28justin_smitherr, s/loop/recur means the same thing in this case effectively
22:28noobie_doesn't do seq force an evaluation?
22:28justin_smithnoobie_: yes, you won't get any result unless you force the lazy input
22:28tolstoyOne more fix! ;)
22:28justin_smithrecur is strict to
22:29justin_smithnoobie_: doseq performs some action for every item in an input, perhaps you are thinking of doall or dorun which are meant for forcing laziness
22:42TrioxinI'm going to attempt to make an applet out of clojure and load it into nwjs where my jar will run and interact with the javascript and clojurescript on the page. If I'm not successful, what would be the second best way to pipe data back and forth between the DOM in nwjs (Basically chromium with node running and DOM/node interop). Let's say in the most extreme case this data is a video stream. A local socket? Quantum entanglement?
22:44Trioxinpipe via command line in node even? need fastest route
22:45justin_smithfile mapped to shm
22:45justin_smithmaybe?
22:45Trioxinwhat's shm?
22:46justin_smithshared memory - memory that two programs are both allowed to access
22:46Trioxinoh
22:46justin_smithTrioxin: http://www.boost.org/doc/libs/1_38_0/doc/html/interprocess/sharedmemorybetweenprocesses.html
22:46justin_smithtypically the least safe possible way to share data between programs, also the fastest
22:47justin_smith"Shared memory is the fastest interprocess communication mechanism. The operating system maps a memory segment in the address space of several processes, so that several processes can read and write in that memory segment without calling operating system functions. However, we need some kind of synchronization between processes that read and write shared memory."
22:47amalloyi bet we could come up with less safe ways
22:47amalloymorse code transmitted via the medium of nuclear explosions
22:47Trioxinlol
22:47justin_smithamalloy: heh, how about less safe, and you also have valid reasons to consider using it?
22:50Trioxini bet shm would be even better than applet/JS
22:50Trioxinso jar/node shm
22:51Trioxinsince in nwjs I can run node code in the dom anyway
22:51justin_smithTrioxin: in practice you don't see this sort of thing because it is way easy to crash programs if you do it wrong
22:52justin_smithI was just literally answering the "what's the fastest way to communicate between two programs" question
22:52Trioxinhm
22:53Trioxinpiping is probably crap
22:53Trioxinor is that done at the kernel level?
22:54justin_smithit is, and that makes it slow because of the switches to kernel mode (syscalls are rarely cheap from userland)
22:55justin_smithbut maybe that's just unavoidable considering we are talking about two different programs communicating here
22:55Trioxinso then we have local sockets or if I can get my clj in an applet
22:56Trioxinthere are some oooold examples of clojure applets that java won't run under normal security but i think in the nwjs environment it would run it
22:56justin_smithTrioxin: almost always - make something that works first, then figure out what's too slow and see what you can speed up out of that. Optimizing before your code works rarely turns out well.
22:56Trioxinjustin_smith, there's that but then also the fact that there's a big difference between the code for shm and sockets
22:57Trioxinsockets don't sound too bad actually
22:58Trioxineasy to handle
22:58justin_smithnot a huge difference - your "read" becomes "wait until value is available, then access", your "write" becomes "wait until read access is available, then store"
22:58justin_smitherr, write access, of course
22:59jabbfeels like i'm getting stdin cut off
23:00justin_smithjabb: what's the symptom?
23:02Trioxineh. of course no webrtc lib for clojure up to date I can find
23:02Trioxinmaybe will be my first time trying to wrap my own java thing
23:02justin_smithTrioxin: interop is easy, and people don't take advantage of it as much as they should
23:03Trioxinoh I will
23:03Trioxinthere's still some untapped market share in the p2p space to be had
23:04jabbjustin_smith: http://ideone.com/BZjo30
23:04justin_smithan easy and cool thing would be to port this to clojure, for use in unit-tests with functions that take strings https://github.com/minimaxir/big-list-of-naughty-strings/blob/master/naughtystrings/internal/resource.go#L530
23:06justin_smithjabb: stdout is buffered, in order to make it print you must either use (flush) or something that calls (flush) like (println) - println is not flushing because the input has not ended.
23:06justin_smithline-seq doesn't end until the input is closed
23:07jabbshould close on eof, yeah?
23:07jabbadding flush didn't help
23:07justin_smithin this case, you could change "let" into "doseq" - not because doseq can replace let, but in this case it would incidentally work, and it would print each line of input on a line
23:07jabbhmm
23:07justin_smithjabb: where did you add flush?
23:07jabbafter println
23:08justin_smithprintln doesn't return
23:08justin_smithbecause stdin hasn't closed
23:08Trioxinisn't there another flush method... ob something or other (This was from a different language)
23:08Trioxinthat also had flush
23:08justin_smithjabb: println itself calls flush, but that only helps if it actually finishes
23:09justin_smithyou are asking it to print a value, then it's hanging trying to read more of that value...
23:09justin_smithjabb: like I said, try just changing let to doseq and see what happens
23:09jabbahh
23:09jabbi'm sure that'll work, i'm just trying to use a series of reduces and stuff on input
23:10jabbso doseq wouldn't work for that
23:10justin_smith(reduce println input)
23:10justin_smiththat will also work
23:10justin_smithlater you can replace println with a function that does other stuff too
23:11jabbi tested this with "lein tampoline run > out" and "cat - > out2" and compared the two files
23:11jabbone was larger than the other by 3 characters
23:11jabbsame input
23:11jabbctrl-d on stdin to force a write
23:11justin_smithI bet out had at least one extra newline
23:12jabbyeah, one had a newline, the other had a character missing from the front and back
23:12jabbhere, sec, i'll have you test
23:12Trioxinwhat if... I take all the clojure snippets on the net and feed them to a genetic algorithm for the purpose of meeting a fitness of increasing it's awareness, capabilities, and inferred data via convolutional ANNs?
23:13TrioxinWILL WE DIE
23:13TEttingerTrioxin: you do know what most of my clojure snippets on the net do, right?
23:13Trioxinwhat?
23:13clojurebotwhat is bbloom bitching about OOP
23:13TEttinger,(let[a #(apply str(flatten %))r repeatedly p partition N rand-nth n #(a(N(concat(repeat %"")(mapcat p[1 2 3]%&))))v #(n 0"aioeu""iaai")w(fn[](let[b(n 6"!.""""...")s[(n 0"STKNYPKLG""GlThShNyFt""ZvrCth")(r(N[1 2])#(do[(v)(n 9(map str"'-"(r 2 v)))(n 0(concat"lpstnkgx"[(N["h""gl""gr""nd"])(v)])"rlthggghtsltrkkhshng")]))]][b(if(seq b)[" "s][(n 3",")" "(.(a s)toLowerCase)])]))](re-find #"[A-Z].+"(a[(r 500 w)"."])))
23:13clojurebot"Glax kiarl gliapa-ial! Gliaxult... Pekogg... Piat. Te-okhogg, yaie, zvraxilt, yailt. Thukh pigg. Nyo'ol peggaigr negg zvriat, yiaghai'iarl kiaghex, kuth. Ftogh, fton... Zvrukhigh yash. Cthuuiap kugip nixiak tipaigg, lulogh glih gig... Poggigg. Gakegg kot, kuts kakh shakukh, thaikup cthot. Glai'ukot, nosiaai! Poia, kaitsang. Nugh. Kirl ko-op nyairl! Shos. Pe-ak, ctharliagg nuxiagr zvrix, zvruo! Ke...
23:14jabbjustin_smith: source: http://sprunge.us/WcfH input: http://sprunge.us/OMQF
23:14Trioxinskynet is upon us
23:14TEttingerIa! Ia!
23:15jabbsounds lovecraftian
23:15jabbTEttinger: know me?
23:15TEttingerhm... let me check...
23:16Trioxinjabb is the bottom from meatspin
23:16justin_smithjabb: you are using line-seq on a one line file
23:16jabbjustin_smith: true, but could be more than one
23:16jabbwho knows? :D
23:18fsjhfkjdhfhey this is a bit of a stupid question but how do i insert a list into a list? like let's say i have this list ['(1 2) '(3 4)]
23:18fsjhfkjdhfand i do (take 2 '(5 6 7 8))
23:19jabb,(concat '(1 2) '(3 4))
23:19clojurebot(1 2 3 4)
23:19fsjhfkjdhfthat's not quite it
23:19fsjhfkjdhfit flattens it
23:19fsjhfkjdhfi want it to be ['(1 2) '(3 4) '(5 6)]
23:19justin_smith,(conj '[(1 2) (3 4)] (take 2 '(5 6 7 8)))
23:19clojurebot[(1 2) (3 4) (5 6)]
23:19fsjhfkjdhfthat's what i thought too but it wasnt working..
23:20fsjhfkjdhfhm ill try again
23:20jabbjustin_smith: try my snippet? :)
23:20justin_smithfsjhfkjdhf: remember that conj does not change the input
23:20justin_smithjabb: yeah, playing with it right now
23:20fsjhfkjdhfyeah still doesnt seem to be working hmm
23:20jabbseeing the same discrepency? missing two characters from both ends?
23:21fsjhfkjdhf(def sample [0 1 2 3 4 5 6 7 ])
23:21Trioxinthou shalt copy and paste into thy repl
23:21fsjhfkjdhf(conj (take 2 (drop 2 sample)) ['(1 2) '(3 4)])
23:21fsjhfkjdhfis giving me ([(1 2) (3 4)] 2 3)
23:21justin_smithfsjhfkjdhf: your args are in the wrong order
23:22fsjhfkjdhfomg lol
23:22fsjhfkjdhfthank you
23:24justin_smithjabb: the difference is that the lines coming from line-seq are wrapped in parens
23:24jhnwhy do core.async/map and core.async.reduce operate on different arguments, unlike regular m/r?
23:24justin_smithjabb: this would be easier to see if your input file had more lines, and they were not composed of parens
23:24jhnas in: https://clojure.github.io/core.async/#clojure.core.async/map
23:24jhnvs. https://clojure.github.io/core.async/#clojure.core.async/reduce
23:25jhnmap operates on a collection of channels.
23:25jhnbut reduce operates on the items of a single channel.
23:25jabbjustin_smith: should that matter?
23:26jabbjust two characters
23:26justin_smithjabb: you asked it to print a collection, when a collection is printed the parens are printed with it
23:26jabbunless lisp is eating them?
23:26justin_smithlisp is not eating anything
23:26justin_smithyou asked it to print a list, the parens are how lists are printed
23:26jabbahh
23:26justin_smithso it added parens
23:26jabbhmm
23:26jabbi seee
23:28justin_smithjabb: this version will print the input (reduce #(println %2) nil (line-seq (java.io.BufferedReader. *in*)))
23:28justin_smithstart with that, verify it replicates your input, then put a more interesting function in there instead of #(println %2)
23:30justin_smithjabb: on each call, the fn will get "previous return value" as its first arg, and "next line" as the second
23:37Trioxintettinger, you have site with your codes?
23:38TEttingernot really, that one was written mostly in an IRC window :)
23:38TEttingeroh!
23:38Trioxinit's okay I don't have one either but I shall make one
23:39TEttingerthis is roughly the same sort of output but much clearer input http://ideone.com/L0eHc6
23:39Trioxinfirst i'll fill it with all my lame C# and PHP/MySQL
23:39Trioxinthen...
23:40Trioxinyou know
23:40TrioxinI've done craziness in PHP
23:40Trioxinpushing it to its limits because I learned it first
23:41TEttingera friend used this for his game, actually http://ideone.com/zwnFAL
23:41TEttinger(the output)
23:41TEttingerPlanetary System Cabal (hm, what could possibly go wrong...)
23:44TEttingerIt's kinda strange how very very well-suited clojure is as a language for text processing. it has slow startup at the command line, which is a mark against, but just about every program involving regexes and more importantly sequences of matches is really just so easy to write.
23:44TEttinger(I just wrote some java to do some text handling, it's ugggghhhhh)
23:44justin_smithTEttinger: if you just load up clojure.jar with java, you can get load times ~ 1 second
23:45TEttingeris it lein that slows it down?
23:45justin_smithTEttinger: lein and nrepl
23:45justin_smithboth are pretty slow to start up
23:45TEttingerinteresting
23:45TEttingerhow about boot>
23:45TEttinger?
23:46justin_smithit starts faster, but if you don't need to manage classpath (either you can set it up yourself or only need clojure) java running clojure.jar can't be beat :)
23:46TEttingernice.
23:46TEttingerI didn't expect that
23:47justin_smithTEttinger: try this time java -jar ~/.m2/repository/org/clojure/clojure/1.7.0/clojure-1.7.0.jar -e '(println "hello world!")'
23:47justin_smithshould be closer to 1 second than two
23:48TEttingerhm. I wonder if there's some sort of subset of lein possible that can read a lein project.clj (or some easy to parse version generated from one by a lein plugin) but doesn't try to download deps or anything
23:48justin_smithI mean that's still slow - but it's doable
23:49justin_smithTEttinger: lein cp > classpath; java -cp $(cat classpath) ...
23:49justin_smithyou only need to do the lein cp part once each time you change your deps :)
23:49TEttingergood ol' windows
23:49justin_smithah!
23:49TEttingerI can do >
23:49justin_smithbut you can still put the output of lein cp in a file
23:49TEttingernot sure how I'd do $
23:49justin_smithbut can you get that into a command line,,,
23:49justin_smithright, right
23:50justin_smithedit runclojure.bat
23:50justin_smithhaha
23:50TEttingerthere's powershell...
23:50justin_smithanyway, I'm sure there's a simple way to do it
23:50justin_smithjust put the output of lein cp into the shell script
23:50justin_smithand if the shell script breaks, you can go run lein cp again
23:50TEttingerha
23:52justin_smithTEttinger: there are various options that people don't consider because they assume java is the thing that is making startup of clojure slow
23:59oraclehow to convert [1 2 3 [4 5]] into [1 2 3 4 5]?
23:59oraclemapcat doesn't work since every element need to be a seq
23:59oraclebut only [4 5] is a seq