#clojure logs

2015-03-02

00:47ShayanjmWhat's the difference between doto & ->?
00:53puredangerdoto applies each expression separately without threading the result because it expects to be calling side-effecting functions
00:53_kardandoto cascaded calls & -> chained calls
00:53puredangerwhich is what you commonly get with Java setters
00:58TimMc&(clojure.walk/macroexpand-all '(-> a (b 1) (c 2)))
00:58lazybot⇒ (c (b a 1) 2)
00:58TimMc&(clojure.walk/macroexpand-all '(doto a (b 1) (c 2)))
00:58lazybot⇒ (let* [G__13521 a] (b G__13521 1) (c G__13521 2) G__13521)
01:31jon__getting started with clojure
02:48bucketh3adIs it a good idea to use pmap to run a get/parse function over a list of uri's, or is there a better tool for such a task?
02:51TEttingerbucketh3ad, I think pmap is mostly for cpu-limited computations that need multiple threads, not things that need multiple network connections?
02:51TEttingerI haven't done much with remote getting of content
03:38zotmorning all. i'm having a dumb moment, and hoping that somebody here might have the eyes to combat my blindness. i'm working up a "simple" core.async model for kafka, intended to work with the component library. it's failing miserably, despite having tried to model it off my other working async pub/sub code. i've stripped out the stop code, and made it self standing (instead of component based). the 'send-message' at the end returns, and the '
03:40TEttingermessage cut off after: end returns, and the '
03:40TEttinger^ zot
03:41zotthe 'send-message' at the end returns, and the 'recv-message' just sits waiting. any clues?  https://gist.github.com/anonymous/b639bddfe1f7ea646b1f
03:42zot(also, i would gladly take ideas and suggestions as to how experienced clojurists debug this sort of thing — i'm a bit clueless when debugging async, etc., code in clojure.)
03:43sverizot: not sure about this, but I think I read somewhere you have to take extra steps to get stacktraces from async code
03:43zoti can't even tell if a stacktrace is the problem, or if i'm "doing it wrong" wrt pub/sub in core.async
05:33zotftr, it was something stupid: (async/pub was being called w/ (:publisher this), which is empty at that point in execution.)
06:16devllhi,I am using Component for my project.
06:16devlland calling (.stop (:server component)) in (stop [this ..])
06:16devllwont work.
06:17devllfull code is here. http://pastebin.com/FLhSw2MY
06:17devllwhy?
06:17clojurebotwhy is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone
06:18devllcould anyone explain this to me? thanks.
06:20devlljustin_smith: ?
06:21TEttingerhey devll
06:21TEttingerI'll take a look
06:21devllhi TEttinger ,thanks
06:21TEttingeralso, define "won't work"
06:21devllthrows an exception.
06:22TEttingerwhen you (println (:server component)) , can you also print the (class component) and (class (:server component)) ?
06:23TEttingeralso, which exception
06:23TEttingerNPE would be good to know if it's that
06:23devllthe code I posted works.
06:23devllI commented out one line.
06:24brkpntHi, there is an equivalent way to load a whole project like in Common Lisp asdf:load-system? In other ways to compile my whole project and load it to the repl?
06:24devllwhich throws exception if I use it instead of close-jetty function
06:24brkpntways->words*
06:25devllbrkpnt: tools.namespace maybe help.
06:26TEttingerbrkpnt: setting the :main ns may also help in project.clj
06:26clojurebotExcuse me?
06:26devll(:server component) is a org.eclipse.jetty.server.Server
06:27TEttingerand which exception?
06:27devllwait a sec.
06:28TEttingerit doesn't have a .stop method
06:28TEttingerhttp://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/server/Server.html
06:28TEttingerthere's doStop
06:28TEttingeryou could try .doStop instead of .stop
06:29TEttinger(I agree with your instincts that it should be called stop)
06:29devllit does.
06:29devllplease look at my close-jetty
06:30devllit works
06:30devllIllegalArgumentException No implementation of method: :stop of protocol: #'com.stuartsierra.component/Lifecycle found for class: nil clojure.core/-cache-protocol-fn (core_deftype.clj:555)
06:30devlljetty 9
06:33devlllet me try doStop
06:34TEttingerohhh
06:34TEttingerit has to do with component/Lifecycle
06:36TEttingerI have no idea how stuartsierra's lib works
06:36devllOK.
06:36devllthanks anyway.
06:36devllI will read the code myself.
06:38TEttingerI'm not sure how defrecord works, tbh
06:39TEttinger##(doc defrecord)
06:39lazybot⇒ "Macro ([name [& fields] & opts+specs]); (defrecord name [fields*] options* specs*) Currently there are no options. Each spec consists of a protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args*] body)* D... https://www.refheap.com/98006
06:42devllchanging to doStop gives NPE.
06:43TEttingerinteresting, it is null then somewhere
06:44TEttingeroh, and (assoc component :server nil) won't change component
06:44devllbut close-jetty works perfectly
06:45TEttinger,(def component {:server "something"})
06:45clojurebot#'sandbox/component
06:45TEttinger,(assoc component :server nil)
06:45clojurebot{:server nil}
06:45TEttinger,component
06:45clojurebot{:server "something"}
06:45devllI think assoc is different for Component.
06:46devllnot this immutable way.
06:47TEttingerwhat's the type of component, the arg you get called component?
06:47TEttinger(class component)
07:00zotit should be an Httpserver record
07:00zotand the dissoc/assoc at the ends looks correct to me
07:40Guest7286I have question: I removed core_test.clj and now Leiningen fails to run the other tests. I tried to find a solution, but Google doesn't seem to know how to fix it. Does anyone have an idea how to fix this?
07:48Guest7286never mind, it was a namespace clash that made it happen. sorry aobut that
07:57EremoxIs it possible to create a circular list without creating a new data structure?
08:00schmir, (take 10 (cycle [1 2 3]))
08:00clojurebot(1 2 3 1 2 ...)
08:01schmirEremox: does cycle help?
08:02EremoxThink of a list where the second element is the list itself
08:03hyPiRionEremox: no, cycle is the closest you get
08:03hyPiRionIt's effectively the same thing though
08:03EremoxOK thanks anyway.
08:26ssiderisEremox: you could make your own lazy seq and return whatever you like as the next element
08:26ssiderisdoesn't have to be realized
08:26EremoxYeah thanks I will try it.
08:45sveriHi, did someone here do an app where he receives several chunks on the backend from cljs (like with resumable.js)?
08:45sveriI wonder how to handle the data that comes up
09:40sveriHm, ok, in a different way, I get a org.eclipse.jetty.server.HttpInput in the request. How do I access it's contents or store it on disk?
09:41svericalling .read on it returns -1 which means that the end is reached
09:43llasram`sveri: Two possibilities off the top of my head: (a) the request has no body content (e.g. is a normal GET); (b) something else in your stack is consuming the entire input
09:44sverillasram`: ah, I look the second one up, taking out some middlewares, good idea
09:44ordnungswidrigsveri: it's an inputstream, I typically use "slurp" on it. depending on the content-type of course
09:45ordnungswidrigsvri: you can dump the complete request with `(prn request)` at some point, that might give you some insight
09:46sverillasram: ordnungswidrig hm, it still is empty, even when removing my own questionable middleware, still strange. I am using resumable.js which sends get request with some content. at least get requests are all that get out
09:47sveriordnungswidrig: slurp returns an empty string
09:49mpenet`body in GET is not always supported, it's not clearly defined by the http spec if I recall
09:50mpenet`depending on the server you're using it might just be ignored
09:50sverimpenet`: Yea, I wonder if I am using it the wrong way
09:50mpenet`probably
09:51ordnungswidrigGET does not support a body in all practical applications
09:51ordnungswidrigI think in HTTP/2 they got that clear
09:52mpenet`yup
09:52sverikk, the docs also talk about POST requests
09:52sveriweird
09:58sveriok, thank you, I must be using it wrong, will be looking how to fix this :-)
11:31takosukehello peoples, I got a quick question if anybody is up for it -
11:31Glenjamin~ask
11:31clojurebotThe Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.
11:32takosukelol
11:32takosukeunderstood :)
11:32takosukei want to have a login-required route in flask proxy to a different app
11:32takosukewordpress in this case
11:33takosukethe point is to use only one auth system (the one implemented in flask) to give access to the content
11:33takosukeim thinking of doing some proxy magic with nginx but i cant quite fit the pieces together
11:35takosukesomething like setting up a virtual host for the wordpress app that can only be accessed internally via localhost:9000
11:35justin_smithwhere does clojure fit into this?
11:35takosukeomg
11:35takosukesorry
11:35takosukewrong channel!!
11:35justin_smithheh
11:35takosukelol
11:35xemdetiaso as part of the ask to ask protocol
11:35xemdetiado we send him a reset?
11:35takosukei badly need a reset
12:00sritchiehas anyone seen this? CompilerException java.lang.RuntimeException: No reader function for tag +clj, compiling:(taoensso/sente:606:89)
12:00sritchiecompiling a file at the REPL
12:00sritchiethis happens on my latest Sente upgrade - as far as I know, the cider repl’s not supposed to try and compile raw cljx files
12:02sritchieis it possible to exclude files from a jar dependency?
12:02justin_smithsritchie: well, an easy thing would be to try a regular (non-cider) repl and see if the error is still there
12:02sritchiegood call, trying
12:03the_freyIf I have a massive lazy-seq and I call partition-all on it, then doseq to call some functions on the partitions I run out of memory
12:03the_freyis that because the previous partitions are kept in memory?
12:03the_freyI thought doseq discarded the head
12:03sritchiethe_frey: did you bind the lazy-seq to something?
12:03justin_smiththe_frey: do you have a binding somewhere to the beginning of the list directly?
12:03sritchie(def my-seq ...)
12:03the_freyit's in a let binding yeah
12:04sritchiejustin_smith: still happens at a normal repl
12:05the_frey (let [foo (partition-all 10000 data-seq)] (doseq [data data-seq] load-into-db data))
12:05justin_smithsritchie: cool, so it's not a cider problem
12:05the_freyjustin_smith ^ is a kinda simplified version of what I'm doing here
12:05justin_smiththe_frey: that should not be holding onto the data - unless foo escaped the let block
12:05the_freyis it because it's returning a lazy seq of fully-qualified seqs?
12:05justin_smith(or something using foo escaped the let block)
12:05the_freysorry
12:05justin_smithdoseq returns nil
12:06the_frey(let [foo (partition-all 10000 data-seq)] (doseq [data foo] load-into-db data))
12:06the_frey^ is what I meant
12:06justin_smiththat let block returns nil, so it will not hold onto foo's head
12:07justin_smithand thus that shouldn't leak
12:07the_freyhmmm
12:07the_freythe weird thing is if I fully qualify this lazy seq, it takes like twenty mins but will eventually churn through in linear time
12:07justin_smithI assume load-into-db isn't holding onto it's args after the db transaction?
12:07justin_smithfully qualify?
12:07the_freyholding onto its args in what way?
12:08the_freyfully realize?
12:08justin_smithOK, that's weird
12:08the_freysorry, long day, a bit flu-ey
12:08sritchiejustin_smith: brutal. gonna try publishing my own version of sente with cljx files excluded.
12:08the_freyyeah this way it stays way lower in CPU usage but still dies after a while, so my guess is a leak
12:09justin_smiththe_frey: have you tried profiling? jvisualvm is free, it comes with the jdk, point and click
12:09the_freygood shout
12:10the_freyI will go and have a nose
12:10the_freycheers!
12:13arrdemHas anyone messed with play-clj? I'm trying to find the path of least resistance to drawing a simple sprite & rotation based GUI
12:14xemdetiajustin_smith, I must warn that jvisualvm is sun java only :)
12:14xemdetiaor at least doesn't work with the jvm's I've tried
12:15justin_smithxemdetia: jvm or jdk?
12:15xemdetiajvm, I think I tried using it against ibm jre and it failed
12:16godd22acronym4me
12:16xemdetiaibm jre has other fun tracy-profile options though
12:16ShayanjmHey guys, I'm trying to write a macro that returns a function for a circle given a radius and x/y offsets
12:16Shayanjmhere's what I've got: https://gist.github.com/shayanjm/8773123440a7c8cc2258
12:17Shayanjmmy issue is that when I macroexpand-all to inspect, that inner 't' (the argument to the anonymous function i'm trying to generate) ends up becoming <NAMESPACE>/t -- which obviously throws an error when used
12:17arrdemShayanjm: the inner t needs to be a gensym. try using the token t#.
12:17justin_smithxemdetia: openjdk has a visualvm project, checking whether they include it with their jdk, I thought they did
12:18xemdetiaoh I forgot about openjdk
12:18xemdetiaIt might indeed work there
12:18ShayanjmExcellent thanks a lot arrdem. I've been on python for a while so i've forgotten my clj know-how :(
12:19Shayanjmyou still in ATX btw?
12:19arrdemShayanjm: you remember what -# does in the context of `? yep.
12:19arrdemwe never did get coffee :P
12:19ShayanjmI'm pinning that on you ;)
12:19arrdemI'll take it
12:20Shayanjmumm, i can't really articulate what -# does in the context of ` but my best swing is that it generates a symbol to be used within the context of the result of the macro?
12:20sritchieambrosebs: hey hey
12:20sritchiethis is easier than twitter
12:20Shayanjminstead of evaluating immediately, or evaluating upon generation
12:20sritchieambrosebs: right when I include core.typed I get that error from piggieback (with cljs excluded from core.typed)
12:20sritchieambrosebs: I’d love to get my team switched from schema to a real type system
12:21justin_smithShayanjm: it escapes the auto-namespacing of `, while using a gensym to prevent accidental capture of symbols from the place the macro is used
12:21arrdemShayanjm: in ` context, -# postfixed symbols are named gensyms. It's equivalent to wrapping your ` form with (let [t (gensym "t")] `...) and using ~t instead of t#
12:21Shayanjmahhh
12:22arrdemShayanjm: if you want an unqualified, named symbol `~'foo is the raw symbol foo. Handy sometimes if you actually do want closures or named parameters.
12:22ShayanjmGotcha
12:22Shayanjmarrdem: have you graduated?
12:23arrdemneg. spring next year.
12:23Shayanjmsweet, any solid plans after grad?
12:23Shayanjmor gonna cross that bridge when it comes?
12:24arrdemlolno I'm just trying to get graduated first. bomb that bridge when I get to it.
12:24Shayanjmlolol can respect
12:24arrdemwill be at Factual over the summer... so hopefully amalloy et all won't get sick of me :P
12:26Shayanjmsounds like fun
12:29arrdemI sure hope so
12:39Kristienhi
12:41justin_smithhello and welcome to the beautiful world of Clojure programming
12:44KristienI love this wonderful world already!
12:44justin_smith(inc puredanger)
12:44lazybot⇒ 33
12:44justin_smithfor that clojure.inspect link on stackoverflow
12:45justin_smithI had no idea!
12:45puredanger:)
12:46justin_smithit's just too bad there isn't a "mutable" version that has a single display, and lets you push things to it from the repl
12:47Glenjaminthat exists
12:47Glenjamini've seen it
12:47justin_smithin some lib?
12:47Glenjaminif i could only remember what it was called
12:47arrdemThere is no new code.
12:47justin_smithhaha
12:47justin_smithbecause I don't want to pop a new frame for every request
12:47Glenjaminit's like a fancy logging/tracing thing that sends the forms to another file
12:48Glenjamins/file/process/
12:48justin_smithbut I could totally use a thing that showed a tree of the most recent request
12:48Glenjaminand has a web interface
12:48justin_smithright, schmetterling does something like this
12:48Glenjaminand let you say "record the next N events and show me"
12:49Glenjaminthat's going to really bug me
12:50Glenjaminmaybe it's https://github.com/relevance/mycroft
12:51Glenjamini don't think that's what i was thinking of :s
12:51godd2Mycroft Holmes?
12:52justin_smithman, those software company names - "relevance" "factual". I guess "voodoo" and "enigma" were already taken.
12:52Glenjaminaha
12:52Glenjaminhttp://matthiasnehlsen.com/blog/2014/11/14/Inspect/
12:52Glenjaminthat's the one
12:55justin_smithcool
12:55justin_smith(inc Glenjamin)
12:55lazybot⇒ 15
12:56justin_smithGlenjamin: that dude's book looks interesting too, I hope he finishes it
12:57Glenjaminthere's also a talk https://skillsmatter.com/skillscasts/6031-birdwatch-building-a-system-in-clojure
12:57justin_smithI prefer books myself, but good to know
13:27daniel`im trying to write a friend workflow with multiple challenges/steps, how could/should I share data between steps that the client should never recieve?
13:30justin_smithdaniel`: you can use an in-memory ring session
13:30justin_smithall the client gets is a key used on the server side to look up the session
13:31daniel`mhm, right, a random token or something
13:31daniel`i was wondering what to use to safely identify the user between steps
13:31justin_smithdaniel`: yeah, it is built into ring's session stuff if you use the in-memory option
13:32justin_smiththe user gets a cookie with their session id
13:32daniel`i already have db sessions setup for another worflow
13:32daniel`workflow
13:32justin_smithOK
13:32justin_smithso you could probably leverage that. You may need ssl to ensure the cookie is not snooped / stolen though?
13:33justin_smithor use ring-anti-forgery
13:33justin_smithhttps://github.com/weavejester/ring-anti-forgery
13:34daniel`thanks, will look into it
13:35daniel`its not a huge concern as the data the server returns back should be encrypted
13:35daniel`and won't be usable to anyone anyway
13:38justin_smithdaniel`: depending what is hapening, you would want to look out for people using the cookie to make changes they should't be authorized to make
13:40daniel`yep, definitely justin_smith
14:20ambrosebsget got into gsoc!
14:20ambrosebs*we
14:21havenwood\o/
14:21justin_smithcool
14:22ro_stonly good things happen when you get time to work on OSS. well done, ambrosebs!
14:28ajmagnificoAnyone have any thoughts on this stack trace? http://cl.ly/image/0p162k160o0S
14:29agarmanyou have recursion that doesn't end
14:29justin_smithajmagnifico: sounds like a recursive concat bomb
14:29ajmagnificoIt fills up 1024 frames in the stack trace, repeating the same pattern over and over again
14:29ajmagnificoI do use concat
14:29justin_smithajmagnifico: what can happen, is that you can have nested calls to concat, and if they are not forced before a deep nesting, just getting the first item causes too many layers of lazy-seq realization on the stack, and you get a stack overflow
14:30justin_smiththis can sometimes be fixed by using lazy-cat
14:30justin_smithor otherwise refactoring so you don't have a huge number of concat calls being realized all at once
14:30Scala[beginner lisp question] I'm trying to convert {:foo "1 1", :bar "2 2"} to [:foo [1 1], [:bar [2 2]], how do I map over a dictionary mapping like this?
14:30ajmagnificothx justin_smith, I'll check it out!
14:31justin_smithScala: seq
14:31justin_smith,(seq {:a 0 :b 1})
14:31clojurebot([:b 1] [:a 0])
14:31justin_smithScala: also, map already calls seq on its arg
14:31justin_smithso you can just call map on the hash-map and it works
14:31agarmanjustin_smith: Scala also has a string split happening
14:31llasramAnd a Long/parseLong
14:31justin_smithOK
14:31ScalaI'm not too concerned about that part
14:32justin_smiththat's just details :)
14:32agarmanyep
14:32Scalaso since map will make a 2 element list out of map entries, is there a nice way to have a function expect that but treat it as 2 separate args?
14:32agarmanyou can just use (map (fn ...) {:foo "1 1" ...}) as well
14:32agarmanno need doing seq first
14:33llasram,(map (fn [[k v]] {:key k, :value v}) {:foo "1 1", :bar "2 2"})
14:33clojurebot({:key :bar, :value "2 2"} {:key :foo, :value "1 1"})
14:33llasram"destructuring"
14:33agarman,(map (fn [[a b]] [a b]) {:foo "1 1"})
14:33clojurebot([:foo "1 1"])
14:33justin_smith,(map (fn [[k v]] [k (map #(Long/parseLong %) (clojure.string/split #" " v)) {:foo "1 1" :bar "2 2"})
14:33clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>
14:33llasramheh
14:33justin_smithoops
14:34agarman,(map (vector %1 %2) {:foo "1 1"})
14:34clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: %1 in this context, compiling:(NO_SOURCE_PATH:0:0)>
14:34agarman,(map (vec %1 %2) {:foo "1 1"})
14:34clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: %1 in this context, compiling:(NO_SOURCE_PATH:0:0)>
14:34agarman,(map #(vector %1 %2) {:foo "1 1"})
14:34clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval176/fn--177>
14:34Scalaagarman: I think (fn [[a b]]) is what I was looking for
14:34agarman,(map #(vec %1 %2) {:foo "1 1"})
14:34clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval204/fn--205>
14:34agarmandang it
14:34agarmannvm
14:35justin_smith,(map (fn [[k v]] [k (map #(Long/parseLong %) (clojure.string/split #" " v))]) {:foo "1 1" :bar "2 2"})
14:35clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.util.regex.Pattern>
14:35justin_smithblerg, wrong one ::
14:35agarmanyeah, there's a #(... %1 %2) syntax as well
14:35justin_smith,(map (fn [[k v]] [k (map #(Long/parseLong %) (clojure.string/split v #" "))]) {:foo "1 1" :bar "2 2"})
14:35clojurebot([:bar (2 2)] [:foo (1 1)])
14:35justin_smiththere we go!
14:37engblomHow is clojure storing a list? Is it keeping a count variable updated or will (count my-list) traverse the list in order to tell the length?
14:37justin_smithajmagnifico: ##(nth (iterate #(concat nil % []) [1]) 10000)
14:37lazybotjava.lang.StackOverflowError
14:38justin_smithajmagnifico: ##(nth (iterate #(concat nil % []) [1]) 10)
14:38lazybot⇒ (1)
14:38agarman,(counted '(1 2 3 4 5))
14:38clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: counted in this context, compiling:(NO_SOURCE_PATH:0:0)>
14:38rhg135engblom: for lists it's linear
14:38justin_smithnotice the only difference is the number of concat calls that got stacked up
14:38agarman,(counted? '(1 2 3 4 5))
14:38clojurebottrue
14:38rhg135for vectors a count is kept
14:38engblomrhg135: Thanks!
14:38rhg135np
14:39agarman,(counted? {1 2 3 4})
14:39clojurebottrue
14:39agarman,(counted? (range 1000))
14:39clojurebotfalse
14:39justin_smith,(counted? (cons 1 nil))
14:39clojurebottrue
14:39justin_smithI had no idea///
14:40engblomAccording to what agarman man got the bot to tell, the length of a list seem to be stored
14:40engblom(doc counted?)
14:40clojurebot"([coll]); Returns true if coll implements count in constant time"
14:40Scalaagarman: I think (fn [[a b]]) is what I was looking for
14:40Scalawhoops
14:40agarman,(counted? (seq 1 2 3))
14:40clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/seq--4091>
14:41agarman,(counted? (seq '(1 2 3)))
14:41clojurebottrue
14:41justin_smith,(counted? (iterate inc 0))
14:41clojurebotfalse
14:43justin_smithagarman: there's an inherent race condition between reading the line, and sending it to irc
14:43justin_smithagarman: and we all get to see your retries :)
14:43agarmanjustin_smith: mostly trying to hit enter before you've answered the question
14:43justin_smithhehe
14:44justin_smiththat's another kind of race
14:44agarmanit's a race I'm not likely to win
14:44agarman(inc justin_smith)
14:44lazybot⇒ 201
14:44agarman(dec agarman)
14:44lazybotYou can't adjust your own karma.
14:45agarmanjustin_smith: keep the throttle to the floor. it appreciated by more than just me.
14:46arav93Hi!
14:47arav93And thank god Clojure got in :)
14:47agarmanhi arav93
14:47arav93Hi agarman
15:29maddprofHello all - I'm hoping I'm in the right channel, but I'm looking for some help writing a batch file that sets a few environment variables then executes a jscript file
15:30justin_smithmaddprof: I don't think clojure is likely to help you with that
15:30justin_smithit's a great language, but not great for batch files
15:30maddprofjustin_smith: any recommended channels? I've posted a question on superuser, but being a new member there I'm not really expecting any traction
15:31justin_smithI don't know, maybe if there is a windows related channel?
15:31maddprofokay thanks, back to google I go!
16:22Scalawhat is the idiomatic way to join strings in a list conditionally. ["a", "b"] -> "a, b" but ["a"] -> "a"
16:23justin_smithScala: to me that would usually be a sign of some mistake being made
16:23amalloyScala: that's not really conditional at all, that's just how joining works. see clojure.string/join
16:23justin_smithoh, n/m, amalloy is right, I misread :)
16:23Scalaoh, derp
16:23justin_smith,(clojure.string/join "," ["a"])
16:23clojurebot"a"
16:24justin_smith,(clojure.string/join ", " ["a" "b"])
16:24clojurebot"a, b"
16:24justin_smith(pretend I used ", " the first time too, the result would have been the same)
16:25godd2He's lying
16:26justin_smith:)
16:26justin_smith~justin_smith
16:26clojurebotjustin_smith sits on a throne of lies
16:27SegFaultAXjustin_smith: You smell like beef and cheese, you don't smell like justin_smith!
16:28justin_smithSegFaultAX: how did you know I had beef tacquitos for breakfast! what witchcraft is this!
16:30amalloyjustin_smith: you had me worrying it might actually be spelled tacquito
16:31justin_smithoh man...
16:32amalloywhich just makes no sense at all in spanish, but who knows what kind of tragedies english has wrought
16:32Kristientacquito programming is tacit programming in Spanish
16:33amalloyKristien: eh?
16:38crazydiamondHi. What's best practice for doing testing in Clojure? Is it better to keep tests (calls to deftest and run-tests) in the same file where functions are or separate one?
16:38justin_smithcrazydiamond: run-tests shouldn't be in any of your files - use a tool like "lein test" to find and run all your tests
16:38justin_smithand put tests in their own test namespaces
16:39crazydiamondjustin_smith, ok, so, let's say I want to do TDD in vim?
16:39justin_smithyou can also call run-tests from the repl if you want to do tdd
16:39devll(sh "rmdir" "*" :dir "resources/ghosts/output")
16:39crazydiamondaha, ok, thanks
16:39devllwhy "*" does not work?
16:41devll** why does not "*" take effect?
16:42justin_smithdevll: I'm not sure, maybe you explicitly have to tell the shell it spawns to turn globbing on?
16:42hiredman* is a shell glob, it is expand by the shell, sh is, despite its name, not actually executing commands via a shell
16:43justin_smithhiredman: oh, that would explain it. I was looking at the source but had not gotten that deep yet.
16:43justin_smith(inc hiredman)
16:43lazybot⇒ 73
16:43devllOK . (inc hiredman) thanks.
16:44crazydiamondis there a vim plugin to auto-pretty-indent Clojure code in current buffer?
16:44justin_smithdevll: yeah, this works here: (sh "sh" "-c" "echo *")
16:45justin_smithcrazydiamond: yeah, I think there is a vim integration for clj-fmt
16:45justin_smithhttps://github.com/weavejester/cljfmt
16:47crazydiamondbtw, as long as this is an utility https://github.com/weavejester/cljfmt
16:47crazydiamondmay I install it globally?
16:47justin_smithcrazydiamond: you may want it as a :plugins entry in ~/.lein/profiles.clj
16:48justin_smithcrazydiamond: which is exactly what it recommends doing on the readme
16:48crazydiamondyep, and what to run afterwards? lein deps while being in my home dir?
16:48justin_smithno, deps is always implicit
16:48devllthanks . (inc justin_smith)
16:48justin_smithand installs are always per-user
16:49justin_smithso you can just add it to your :plugins then run "lein cljfmt check" or use the vim binding for it or whatever
16:49devll(inc justin_smith)
16:49lazybot⇒ 202
16:49crazydiamondaha
16:49crazydiamondcool, thanks!
16:55sritchieambrosebs: hey
16:55sritchieambrosebs: around?
17:13profilI am having trouble with referring a macro, I am doing "(ns my-namespace (:require [gloss.core :as g :refer-macros [defcodec]]))" and then I try to use defcodec directly but getting "Unable to resolve symbol". If i do g/defcodec I can access it. Whats wrong?
17:14ztellmanprofil: as far as I know, :refer-macros is a cljs thing, and Gloss is JVM-only
17:14justin_smithyeah, clj will just ignore the :refer-macros key afaik
17:14profilahh that makes sense :D
17:15profilso I can just refer a macro as usual then?
17:15profilyes, that worked, thanks guys
17:17crazydiamondbtw, when doing TDD in Clojure, how to struggle with constant problems like "there was some (def foo ...), and after I removed it it appears again". I'm doing :%Eval (in vim plugin fireplace) to run tests (actually I often ant to see just output of some command, not perform test)
17:17justin_smithcrazydiamond: reloading a namespace does not eliminate defs that are removed from the ns
17:18crazydiamondyep, I realized that. so I probably must remove (ns ) form top of the file
17:18justin_smiththat won't help
17:18crazydiamondthat a am evaluating
17:18crazydiamondso, I wonder what's correct way
17:19justin_smithcrazydiamond: there is a function to remove a var, I am trying to find it (forgot the name)
17:19crazydiamondbut, isn't there some more general approach?
17:20crazydiamondlike forgetting about what was there just some time before
17:20crazydiamondI mean, reloading
17:20justin_smithclojure.tools.namespace has some stuff for this
17:20justin_smithbut no, loading the file does not delete definitions
17:20crazydiamondI am using this
17:20crazydiamond(require 'clojure.tools.namespace.repl)
17:20crazydiamond(clojure.tools.namespace.repl/refresh)
17:21crazydiamondin the end it would turn so that I would need re-launch repl every time
17:21crazydiamondwhich is incorrect and just ugly
17:22justin_smithcrazydiamond: ns-unmap will delete a var from a namespace
17:22crazydiamondthanks, but provided some name...
17:23justin_smithns-publics will give you all vars in a given namespace
17:23justin_smith(well, all that are visible outside that namespace)
17:24crazydiamondbut... aren't there just some best-practices?
17:25justin_smithrunning lein check or lein eastwood will tell you when you have code that reflects definitions that no longer exist
17:26justin_smitheastwood is generally helpful, in other ways as well
17:30crazydiamondhowever, doing :%Eval in vim... that should be equivalent of just throwing that bunch of code into REPL?
17:31justin_smithright
17:31justin_smithwithin the apropriate namespace context
17:33ScalaI'm checking program args when running the program. If they fail my check I want to print a line and exit. An if statement only lets me run one action though, and putting both actions in a function with no args doesn't run. What's the proper way to do this?
17:33justin_smithdo
17:34justin_smith(do (println "message") (System/exit 42))
17:34justin_smithalso, this may be a good place to use when (which like functions contains an implicit do)
17:35justin_smith(when we-outta-here-homies (println "bye") (System/exit 42))
17:36justin_smithwhen is if with a do block and only one branch
17:44Geeky_VinHello Fellow Clojurers! I have a simple doubt could some help me. I have a string, "{\"result\" : \"some value\"}" now How do I convert it to just {result: some value}
17:45justin_smithGeeky_Vin: you can use cheshire or clojure.data.json
17:46justin_smithwait, that would give you {:result "some value"}
17:46justin_smith{result: some value} is not a valid clojure form
17:49Geeky_Vin@justin_smith yeah but not if you set the third value as true ;)
17:50havenwoodGeeky_Vin: Deserialize the JSON?
17:50Geeky_Vinoh wait I see what you mean
17:50Geeky_Vinbut still thats enough for me!
17:50havenwood(json/read-str "{\"result\" : \"some value\"}") #=> {"result" "some value"}
17:50Geeky_Vin@havenwood yes Haven
17:51Geeky_Vin@havenwood but I need to preserve the map value
17:51Geeky_Vinin map: form or :map value
17:51Geeky_VinI mean key sry
17:52Geeky_Vini.e key : value or :key value
17:53havenwood(json/read-str "{\"result\" : \"some value\"}" :key-fn keyword) #=> {:result "some value"}
17:53havenwoodGeeky_Vin: Like that ^ or am I still not getting it?
17:55Geeky_Vin@havenwood oh yeah thats better its equivalent to parse-string in cheshire btw
17:55havenwoodGeeky_Vin: Like the second example here?: https://github.com/dakrone/cheshire#decoding
17:58Geeky_Vin@havenwood yeah.
18:01nicferrier,ping
18:01clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ping in this context, compiling:(NO_SOURCE_PATH:0:0)>
18:04justin_smith$ping nicferrier
18:05nicferrierjustin_smith: :-) - I thought I was in #emacs.
18:05justin_smithhmm, I wonder if that plugin broke
18:05justin_smith$ping
18:05lazybotjustin_smith: Ping completed in 0 seconds.
18:06justin_smith$ping example.com
18:06lazybotjustin_smith: FAILURE!
18:12amalloyjustin_smith: lazybot's website-pinging feature never made much sense to me
18:15Glenjamin$ping isup.me
18:15lazybotGlenjamin: Ping completed in 0 seconds.
18:16crazydiamondIs there way to create new namespace for which result of ns-refers wouldn't be empty and switch to it?
18:16justin_smithcrazydiamond: ns
18:16bucketh3adI've got a doseq with two side-effect functions that operate over a sequence. What is the best way to change (doseq [s my-seq] (func1 s) (func2 s)) so that it runs ALL func1's first then ALL func2's, rather than in pairs for each element of the sequence?
18:16justin_smithor you can manually call clojure.core/refer-clojure within that ns
18:16amalloyjustin_smith: you know about lazybot's actual useful pinging feature though, right?
18:16crazydiamondjustin_smith, ok, but given some name?
18:17amalloywhere you write "amalloy: ping", and lazybot will PM you when he notices me talking in any channel
18:17justin_smithcrazydiamond: I guess you could use create-ns and refer-clojure, but why do you need to create namespaces at runtime anyway?
18:17crazydiamondjustin_smith, I want to create ns with random name each time I'm doing :%Eval. that crazy hack
18:17amalloybucketh3ad: you write it as two doseqs
18:18amalloyyou want to walk over the seq twice, not walk over it once doing two things, so that's what you have to write
18:18crazydiamondjustin_smith, 'cause Clojure isn't about updating and deletion. it's about creating new :D
18:19bucketh3adamalloy: Thanks! That seemed like the right path, but I wasn't sure if there was a more idiomatic method.
18:21amalloyi mean, you can do some silly business if you want, but it's silly. like just for fun: ((reduce (fn [f s] (fn [] (do (thing1 s) (f) (thing2 s)))) (fn []) myseq))
18:22amalloywhich is not quite right since it does like (f1 c) (f1 b) (f1 a) (f2 a) (f2 b) (f2 c)
18:23bucketh3adYeah, that is pretty silly
18:32crazydiamond(eval `(ns ~(gensym)))
18:33crazydiamondlet the testing begin
18:33akkadis there away to avoid duplicate function names? some dev overwrote my function without knowing it.
18:33akkadno errors popped up anywhere
18:34Glenjaminakkad: namespaces?
18:34akkadthis happens to be the same namespace
18:34Glenjaminsmaller namespaces? :p
18:34akkadjust looking for compiler options to assert on this like CL
18:35Glenjaminhttps://github.com/jonase/eastwood might have it
18:35Glenjaminaha, here we go
18:35Glenjaminhttps://github.com/jonase/eastwood#redefd-vars
18:36akkadperfect thanks
19:01Bronsa,(. Double -POSITIVE_INFINITY)
19:01clojurebotInfinity
19:01Bronsa,(.-POSITIVE_INFINITY Double)
19:01clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: POSITIVE_INFINITY for class java.lang.Class>
19:01Bronsa:|
19:02Glenjamindoesn't .- only work on instances?
19:02amalloywell, evidently that is so
19:02Glenjaminweird that (. class -field) works tho
19:03Bronsai'm not sure that the failing case is intentional
19:03Glenjamin,Double/POSITIVE_INFINITY ; is the recommended way though?
19:03clojurebotInfinity
19:04amalloyyes
19:04BronsaGlenjamin: sure but that should just be sugar over .
19:05amalloyBronsa: it is
19:06amalloyit's sugar over (. Double POSITIVE_INFINITY), with no -
19:09Bronsaamalloy: I cannot read anywhere that the .- field access syntax should not work for static fields and should only work for instance fields
19:09Bronsaso I think it should be reasonable to expect (.-POSITIVE_INFINTY Double) to work
19:11Bronsawrt (. foo -bar) behaving like (.-bar foo), no idea if that's by design but it's definitely supported by both clj and cljs and cljs explicitely uses it
19:11Bronsaso I just always assumed it was intentional
19:12amalloyi imagine in cljs both forms work, right?
19:12Bronsayeah, in clj too
19:12Bronsa,(deftype x [y])
19:12clojurebotsandbox.x
19:12Bronsa,(.-y (x. 1)
19:12clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
19:12Bronsa,(.-y (x. 1))
19:12clojurebot1
19:13Bronsa,(. (x. 1) -y)
19:13clojurebot1
19:15blake_OK, so, I'm catching exception in some code, the idea being to catch all the exceptions and return them as a seq.
19:15blake_But what happens instead is I'm eating them. Or at least some of them. java.lang.NullPointerException in particular.
19:16blake_It actually looks like other exceptions are returned. Since I'm not discriminating, I don't see how it can happen.
19:17blake_I have some code https://www.refheap.com/98037 but I'm not sure how instructive it is.
19:17zengyexit
19:18blake_Maybe it's eating them all and the code just doesn't build the error list I think it's building. (I make a vector out of the exceptions and return that.)
19:30blake_Eh. Maybe just rewrite the code so it's easier to debug. =/
19:32justin_smithblake_: ##(key nil)
19:32lazybotjava.lang.NullPointerException
19:32justin_smithblake_: via that specific circumstance (which I think could absolutely happen), you get an exception that breaks out of your catch block
19:32justin_smithand does not get added to the vector of caught exceptions
19:34justin_smithblake_: another factor here is ##(dorun (map inc (range 1000)))
19:34lazybot⇒ nil
19:34blake_justin_smith: Interesting. It shouldn't be possible here but that's a good sign that I wouldn't be looking for it.
19:34justin_smithbecause dorun returns nil, you will never see the results of that keep function
19:35blake_justin_smith: OK, did the dorun....crap...
19:35justin_smithincluding the vectors created by catch
19:35blake_Well, that explains THAT.
19:35justin_smithyou probably want doall
19:35blake_(inc justin_smith)
19:35lazybot⇒ 203
19:35blake_Holy crap! I missed your bicentennial!
19:35justin_smithhaha
19:36blake_I had cake planned and firecrackers...
19:36patchworkblake_: It was quite an event, we were wondering where you were
19:37blake_Debugging!
19:37patchworkI tried to save you some cake but... you know these monsters
19:39blake_I'll set the building on fire.
19:45blake_##(key nil)
19:45lazybotjava.lang.NullPointerException
21:22emaczenWhat is wrong with this multimethod form?
21:23emaczen(defmulti pushable? :Pile :Pile)
21:23justin_smithwhy do you list the dispatch twice?
21:23emaczenI want to dispatch on two "piles"
21:23justin_smiththat's not how defmulti works
21:24justin_smith(doc defmulti)
21:24clojurebot"([name docstring? attr-map? dispatch-fn & ...]); Creates a new multimethod with the associated dispatch function. The docstring and attr-map are optional. Options are key-value pairs and may be one of: :default The default dispatch value, defaults to :default :hierarchy The value used for hierarchical dispatch (e.g. ::square is-a ::shape) Hierarchies are type-like relationships that do not depend upon type inheritance. By default Clo
21:24emaczenOkay, so I have to make a different dispatch function
21:24justin_smithwhat do you expect to dispatch on?
21:24justin_smithtwo args?
21:25emaczenYes
21:25justin_smith(defmulti pushable? (fn [a b] [(:Pile a) (:Pile b)])) maybe
21:25justin_smiththat would treat each order pair of :Pile as a separate dispatch
21:26emaczenjustin_smith, thanks that is what I am looking for
21:28justin_smithyou could also make the dispatch function varargs if you wanted other arities to be acceptable
21:36emaczenwhat is the function for pushing/appending an element to a collection?
21:39justin_smithemaczen: push (for vectors)
21:39TEttinger(doc conj)
21:39justin_smithno such function for lists
21:39clojurebot"([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."
21:39amalloyjustin_smith: ...
21:39amalloyconj, not push'
21:39justin_smithconj
21:39justin_smiththat was a weird brain fart...
21:39justin_smithsorry
21:39TEttingerhaha
21:40justin_smith~justin_smith
21:40clojurebot
21:40amalloy*chuckle*
21:40TEttinger,(def ☃ conj)
21:40clojurebot#'sandbox/☃
21:40TEttinger,(☃ [1 2 3] 4)
21:40clojurebot[1 2 3 4]
21:40amalloy~amalloy
21:40clojurebotamalloy is nuts for juxt
21:41TEttingerclojurebot: TEttinger |is| putting BOMs in all your strings while you sleep
21:41clojurebotOk.
21:43emaczenso conj for vectors but nothing for lists?
21:43TEttingerconj for vectors at the end, conj for lists at the start
21:43amalloyemacsnw: conj adds to a collection in "the natural place", which is different for each kind of collection
21:43amalloyfor vectors, it's at the end
21:43TEttingerif you want to attach to the end of a list, that's the worst case for lists, but you can use ##(concat '(1 2 3) [4])
21:43lazybot⇒ (1 2 3 4)
21:44TEttingerconcat appends sequences
21:44TEttingerwhich includes lists and vectors and even maps
21:44justin_smithand you can fake something similar with into for prepending on a vector (once again, worst case)
21:45justin_smith,(concat "hello" "world")
21:45clojurebot(\h \e \l \l \o ...)
21:45justin_smith:P
21:45TEttinger##(concat '(1 2 3) {:☃ 4})
21:45lazybot⇒ (1 2 3 [:☃ 4])
21:45TEttinger##(concat '(1 2 3) {:☃ 4 :☃☃☃ 10})
21:45lazybot⇒ (1 2 3 [:☃☃☃ 10] [:☃ 4])
21:46TEttingernote how maps aren't ordered and get split into key-value pairs when treated as a seq
21:51emaczenwhat is pop!
21:52justin_smithit's like pop, but for transients
21:52justin_smithor as we like to call it, hobo soda
21:52emaczenYou beat me to the next question -- what are transients?
21:52justin_smithoptimized data structures for updating, if you don't need to access the older values
21:53justin_smithwhen you are done punching them you can turn them into normal persistent data structures with persistent!
21:53emaczenIs there anything like (push (pop l1) l2)
21:54justin_smithwell, it would be conj or into
21:54justin_smithnot push
21:54TEttingerso, you wouldn't change the value of l1 there because lists are immutable
21:55emaczenWhat can I do to get this functionality?
21:55TEttinger,(conj '(2 3) (head '(1 2 3)))
21:55clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: head in this context, compiling:(NO_SOURCE_PATH:0:0)>
21:55TEttinger,(conj '(2 3) (first '(1 2 3)))
21:55clojurebot(1 2 3)
21:55justin_smithTEttinger: peek works on lists
21:55amalloyjustin_smith: but not seqs in general, sadly
21:55justin_smithright
21:56amalloyit's one of the few reasons list? isn't totally useless
22:00justin_smith,(map #(instance clojure.lang.IPersitentStack %) [[] () (iterate inc 0) (range) {}])
22:00clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: instance in this context, compiling:(NO_SOURCE_PATH:0:0)>
22:00justin_smithoops
22:00justin_smith,(map #(instance? clojure.lang.IPersitentStack %) [[] () (iterate inc 0) (range) {}])
22:00clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.lang.IPersitentStack, compiling:(NO_SOURCE_PATH:0:0)>
22:00justin_smith,(map #(instance? clojure.lang.IPersistentStack %) [[] () (iterate inc 0) (range) {}])
22:00clojurebot(true true false false false)
22:18emaczenwhy can't I pop a lazySeq?
22:18emaczenWhat can I do to a lazySeq?
22:20TimMcemaczen: "rest" gives you the lazy seq minus the head, and if that's not pop, I don't know what is
22:21emaczenTimMc: THanks
22:21TEttingerif you want one element, first or nth, if you want a different lazyseq, rest
22:21emaczen(swap! state update-in :deck rest)
22:21emaczenUnsupportedOperationException nth not supported on this type: Keyword clojure.lang.RT.nthFrom (RT.java:857)
22:21TimMcThere's also "next", but that's only if you want an empty result to be expressed as nil, not ().
22:21amalloy[:deck]
22:21emaczenHere (:deck @state) is a lazySeq
22:22emaczenI'm not sure why I can't use rest in this context
22:22amalloyemaczen: [:deck], not :deck
22:22amalloyit's entirely unrelated to lazy seqs, you are using update-in wrong
22:23TEttingerupdate-in takes a vector of things to go "in" to
22:23emaczenwhy do I have to use the []?
22:23emaczenOkay, I see
22:23amalloy&(doc update-in)
22:23lazybot⇒ "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."
22:23emaczenThanks TEttinger
22:23TEttingernp!
22:23emaczenI'm still getting used to the documentation...
22:24amalloyi think clojure 1.7 is going to include an update function, which would behave like you imagined update-in does
22:24amalloybut i haven't been paying attention to that plan for a while
22:28ob_learned about the first thread macro (`->) tonight and it made me happy :)
22:28ob_thread first rather lol
22:30TEttingerit's a good one!
22:30ob_i can't believe ive been more than one tutorial deep without learning about it
22:31ob_"Hey world, clojure is like hacking on linux. See, we have pipes in the form of arrows!"
22:32emaczenhow many functions warrants a thread first ?
22:32gfrederickstwo?
22:32raspasovob_: also take a look at https://clojuredocs.org/clojure.core/some-%3E , it can be useful in some cases
22:32justin_smith3
22:32gfredericksI'll sometimes use cond-> and some-> with just one
22:32emaczenis there a general consensus?
22:32amalloythat's the wrong question to ask
22:33amalloythere's not some "cost" to having nested parentheses that -> alleviates, and above a certain level you need -> to survive. you use -> whenever that lets you rearrange your code into an order that's more readable
22:34TEttingerI just use (((((((((((((((((())))))))))))))))))))
22:34ob_-> makes reading clojure to a newbie like me totally sane now
22:34ob_-> is clojure's secret weapon and it doesnt even know it
22:34TEttingerheh, it's true
22:36raspasovbut the BEST jedis, they only code in nested (). why? because they can see the future :)
22:37amalloyhuh?
22:37raspasovlol I'm kidding
22:37raspasovbecause if you don't use -> the code is backward, i.e. you need to be able to see "forward" in time to understand it lol
22:38amalloyi don't get the "code is backward" argument. we talk that way in english all the time. verb the noun. verb and verb the adjective noun
22:39raspasovmaybe "inside out?
22:39amalloyis "drive the car" inside out?
22:39justin_smithamalloy: but in reverse application order, where the last verb is the first applied?
22:39amalloyi love -> at least as much as the next guy, but so many of the arguments for using it don't make any sense
22:40justin_smithI sleep after I walk home after I go out with some friends after I work after I get up and have coffee
22:40raspasovhaha
22:40justin_smiththat's how outside in can read
22:41ob_(z(y(x))) vs (-> x y z)
22:41ob_pretty damn easy call
22:41ob_for the uninitiated at least
22:41raspasovhttp://www.yodaspeak.co.uk/index.php
22:43ob_The #1 complaint i see on every thread about clojure ever is "omg parens". Only today did I see a comment about thread first macro halfway down the page.
22:43raspasovob_: the correct macroexpand for this case would be (z (y x)), but I totally agree with you
22:44raspasov(macroexpand-1 '(-> x y z))
22:46puredangerI think -> is great when there is some consistency to the results flowing through the forms (sequences, collections, etc)
22:46puredangerI'm less a fan when the kind of thing being threaded changes in every line
22:46puredangeralthough occasionally I see it used to good effect
22:46justin_smithif it has an assembly-line like logic to it
22:47raspasovpuredanger: totally agree, I can't count how many times I've done this and then you have to "deconstruct" your code to actually debug/undestand what's going on lol
22:47justin_smithmy two best use cases are successive transformations that keep the same basic structure, or nested lookup (when get-in just doesn't suffice)
22:47puredangeryes, exactly
22:47ob_I don't know where -> doesn't make sense to use, but as a PR move to get people interested in clojure, it's amazing imo. It copmletely disarms the "omg parens" crowd
22:47justin_smithob_: yeah, less parens than java
22:48puredangerobjection to parens is, as we know, silly. but it's also real.
22:48ob_then again do you want people in the community that will ignore all the goodness bc of parens?
22:48ob_i think the benefits outweigh tho. if nothing else, you destroy the #1 barrier to entry
22:48puredangerI don't want to think that way
22:49raspasovwe should just fork Clojure and make it like Python, that will solve all of the world's problems
22:49ob_yea me either im not into that "pain is good" stuff
22:49justin_smithob_: yeah, actually my first response to "omg parens" is usually "they are a cost of entry, and it's worth it" - if someone still can't handle the parens, that's their loss
22:49puredangerI want to find ways to have people put that reactive fear aside long enough to notice everything else
22:49justin_smithraspasov: at that point you just have ml without the static typing
22:49ob_show them parens and say "if this freaks you out, you can use -> this way:"
22:49ob_parens first, -> second
22:50raspasovjustin_smith: and without the JVM?
22:50lockscan I compile a clojure library into a jar and use it from Java in Android?
22:51justin_smithraspasov: well, who says an ml can't compile to the jvm, I'm just saying that's what the language you end up with would effectively be (once you have immutability, and indentation for nesting)
22:51amalloyob_: -> doesn't even reduce the number of parens except in the absolute least interesting case
22:51justin_smithamalloy: it reduces the depth of them though
22:51amalloy(-> foo (f x) (g y) (h z)) vs (h (g (f foo x) y) z)
22:52locks-> is bad? D:
22:52amalloythat's clearly better-written with ->, but not because of number of parens or depth of anything
22:52amalloyit's because the extra arguments pertaining to h (here, z) are next to h instead of on the opposite side of the expression
22:52ob_the mental strain of going inside out is significant for a newbie
22:52ob_like myself
22:52ob_although at day 7 im getting the hang of it
22:52raspasovamalloy: in nested maps it's nice like (-> deep-nested-map :lvl-1 :lv-2)
22:52ob_but -> as "linux piping" is a freaking revelation
22:53amalloyraspasov: that should be get-in anyway
22:53raspasovyea that's also possible
22:57ob_is there really much interop with java in real world clojure
22:58ob_it almost always reads as a half-hearted benefit rather than something ppl actually do
22:58raspasovob_: depends on what you're doing, if you need an existing java library that does not have a read clojure wrapper, then yes
22:58justin_smithob_: I use it plenty
22:58justin_smithob_: it comes up more when you need a lib for a specific pragmatic thing
22:58raspasovor if you need to use classes like ByteBuffer or other lower-level Java utils
22:58justin_smithit's often easier to just use the java lib for it
22:59ob_oh ok
22:59justin_smithalso, IO tends to be very interop-heavy, beyond the super-basics
23:00justin_smithob_: for abstract and algorithmic stuff outside a tight loop, yeah, you won't see interop. But for specific utilities or places where you need performance interop will pay off.
23:01amalloyit's also easier to work in a mixed team of clojure programmers and infidels if you can just say "okay, we'll write up an interface, and i'll give you an object that implements that interface"
23:01ob_lmao infidels
23:02ob_im guessing clojure programmers are java experts first
23:02amalloysome of them
23:04justin_smithob_: you should see what he does with apostates
23:04justin_smithit isn't pretty
23:04ob_#isis?
23:04justin_smithob_: I learned java after clojure
23:05ob_my dayjob is sql+asp.net mvc
23:05ob_but i sneak in some clojure reading
23:05justin_smithob_: have you checked out clojure-clr?
23:05ob_ive heard about it
23:05justin_smithit's not as mature, but it has the advantage of using an ecosystem you know better
23:06ob_im not heavily invested in clr personally
23:07ob_justin_smith, do you use clojure at work?
23:08justin_smithob_: yeah, I do contract work, back end for web sites in clojure
23:09ob_cool
23:14justin_smithis there a name for that thing Microsoft does where they give a super generic name to software? "windows" "sql server" "mvc"
23:16ob_a marketing term?
23:17justin_smithit's like, attempting to capture the generic term / concept so people will think it implies their version maybe?
23:19ob_sounds like branding
23:19ob_the windows brand, sql brand, etc
23:19ob_sql server rather
23:19justin_smithright
23:20justin_smithit's like the reverse of the kleenex effect - instead of their own brand becoming generic, the generic thing becomes their brand
23:21ob_interesting
23:22ob_but i dont know if ms advertises Windows. Don't they always through version numbers to imply you need to upgrade to the new version?
23:23ob_*Don't they include version numbers
23:24justin_smithyeah
23:25ob_funny how apple went with OS X which sounds like some mainframe
23:25ob_while MS went with something kinda creative with Windows
23:25ob_as far as names go