#clojure logs

2015-12-09

00:00dongcarljustin_smith: wow... clojure syntax is tricky...
00:00justin_smithowlbird: eval is like riding a sherman tank down the block to get a soda from the convenience store two buildings away
00:00owlbirdThe fun will be given to :row-fn while querying data from db.
00:00justin_smithowlbird: maybe you just want identity
00:00justin_smith,(identity 42)
00:01clojurebot42
00:02owlbirdno, it's just a sample code, there may be many styles, each one will has its row-fn to format the result-set
00:02justin_smithowlbird: why would you call eval?
00:03owlbirdif no style fun was found, just return the original value
00:03justin_smithowlbird: eval is like the worst possible way to return the original value, replace it with identity
00:03justin_smiththat's what I was saying
00:03justin_smithalso if you give eval a list with symbols you probably wouldn't like the result
00:04owlbirdoh... I got you
00:04owlbirdmany thx
00:06justin_smithowlbird: eval is for compiling code, it just happens to act like identity for inputs that are not lists
00:06justin_smithor symbols
00:21dongcarljustin_smith: question, when it calls one of the defmethods, is the argument the same as the argument for defmulti or is it ch?
00:22Trioxinit's too bad this doesn't seem to be actively developed anymore https://github.com/arcadia-unity/Arcadia
00:27justin_smithdongcarl: it gets the same argument the dispatch function did
00:31Trioxinwhat would one use in terms of an engine to begin game dev in clojure?
00:33dongcarljustin_smith: can you help me understand what's going on here: https://github.com/shaunlebron/parinfer/blob/master/lib/src/parinfer/reader.cljc#L95
00:33dongcarlor anyone really
00:33dongcarlhere's what a "state" usually looks like https://github.com/shaunlebron/parinfer/blob/master/lib/src/parinfer/indent_mode.cljc#L19
00:34dongcarlit's calling (select-keys state [:x-pos :ch]), but state doesn't have keys :x-pos or :ch
00:34dongcarlstack does
00:34dongcarlso is it just zeroing out the values in stack using conj?
00:37ridcullyTrioxin: libgdx has a wrapper: play-clj
00:39ridcullyTrioxin: depending on the kind of game you plan, something like quil could be enough. also consider clojurescript
02:55visofhi guys
02:56visofwhat is the best effiecient way to read multiple url in parallel?, what i know is make each one in future then use @ for all is this the right solution?
03:16Guest53639%CLEAR
03:16Guest53639CLEAR
03:23riceandbeanswhy does hello world take 13.28 seconds to run?
03:24visofriceandbeans: that's jvm
03:24visofriceandbeans: you run it as jar?
03:25visofriceandbeans: use lein uberjar to get the jar
03:25amalloyit's not the jvm, it's lein
03:26visofamalloy: why lein get all of this time?
03:27amalloybecause it loads a bunch of crap, does a bunch of scanning the classpath? i don't know exactly
03:29riceandbeansgood god
03:29riceandbeans22 seconds to build a hello world jar
03:30riceandbeansok, so java jar hello world takes 5.21 seconds
03:30riceandbeansstill less than awesome
03:31riceandbeansyes, I'm totally judging your language based on hello world
03:37visofriceandbeans: https://github.com/technomancy/leiningen/wiki/Faster
04:30owlbirdwhy do the clojure.jdbc functions like db-do-prepared, update!, delete! return a seq, while the original jdbc API return int
04:50Gamer-ProHello Guys
04:50Gamer-ProDownload this game from here
04:50Gamer-Prohttp://www.indiedb.com/games/spaceshooter-x1/downloads/spaceshooter-x1-update-for-windows
04:50Gamer-ProThis game is the best game of the world
04:55BRODUSanyone know what version of clojure 4clojure uses ?
04:57powered1.6 I think or lower
04:57poweredbecause some 1.7 functions don't work
05:06BRODUSpowered: thanks. I think its at least lower than 1.5 since its not recognizing reduced.
05:36jonathanjif anyone has some time to spare on some code golf, it would be appreciated: https://pb.codehash.net/5276b95b8f404573b3ff1db95717e4ca
06:06parsing_cljHi there! I want to write a parser and im using insta parse
06:07parsing_cljthis is my grammar so far ,modified from the README: http://pastebin.com/3wqcZzLc
06:08parsing_cljI want to parse **THIS IS A HEADLINE**, the same as ** THIS IS A HEADLINE **
06:08parsing_cljso basically ignore the white spaces, does anyone knoe how to do that?
06:11ARM9parsing_clj try '**' for head
06:11parsing_cljARM9: ok
06:15ridcullyjonathanj: the merge looks fine to me. i'd extract that interop chain into something nicely named
06:22visofparsing_clj: you use trim first
06:22visof,(trim "** THIS IS A HEADLINE **") parsing_clj
06:23clojurebot#error {\n :cause "Unable to resolve symbol: trim in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: trim in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: trim in this co...
06:23visof,(clojure.string/trim "** THIS IS A HEADLINE **") parsing_clj
06:23clojurebot"** THIS IS A HEADLINE **"
06:23visofoh
06:24ARM9what did you have in mind?
06:24visofparsing_clj: you can use tokens lib stanfordnlp
06:24ARM9it'd be nice if instaparse had some sort of tokenizer
06:25visofstanford-talk has very good example process-text
06:25l1xhi guys
06:25l1xi am trying to use this java lib in clojure http://basho.github.io/riak-java-client/2.0.1/com/basho/riak/client/api/RiakClient.html#newClient(java.net.InetSocketAddress...)
06:26l1xhttps://gist.github.com/l1x/98a242724dc5762c0677
06:26owlbirdhow to display method name in logs while using tools.logging with log4j
06:26l1xi was wondering why i could not pass in an InetSocketAddress
06:27owlbirdI use the %M pattern, but all methods was shown as "invoke"
06:27visofhave you (import '[com.basho.riak.client.api RiakClient])
06:27visof?
06:27l1xyes
06:28l1xit says no matching method
06:28l1xwhat does ... mean in java? isnt that a linkedlist?
06:28ARM9probably varargs
06:29visofl1x: RiakClient.newClient("192.168.1.1","192.168.1.2","192.168.1.3"); but you pass b
06:29visofis it working with this example?
06:29l1xno this is the java way
06:30l1x (RiakClient/newClient 10017 (java.util.LinkedList. '("127.0.0.1" )))
06:30l1xthe clojure version works
06:30l1xi am wondering what is addresses
06:30l1xor how could i figure out its type
06:32schmirl1x: you need to pass something like (into-array java.net.InetSocketAddress [...])
06:32schmir(as the only argument)
06:33l1xschmir: thanks!
06:35l1xschmir: how would you do that? (into-array (InetSocketAddress. "127.0.0.1" 10017)) Don't know how to create ISeq from
06:36l1x(RiakClient/newClient (into-array [(InetSocketAddress. "127.0.0.1" 10017)]))
06:36l1xlike this :)
06:36l1xthanks!
06:37schmir(into-array java.net.InetSocketAddress [(java.net.InetSocketAddress. "foo" 3123)])
06:44jonathanjso ring.util.io/piped-input-stream uses a nested future to do it's thing
06:44jonathanjSource: https://github.com/ring-clojure/ring/blob/1.4.0/ring-core/src/ring/util/io.clj#L11
06:45jonathanjthe problem with that is that anything that goes wrong in `func` goes completely unnoticed and unhandled
06:47jonathanjwould it make sense to do something like: (let [rethrow #(throw %)] (piped-input-stream (fn [output] (try (... some code ...) (catch Exception e (rethrow e))))))?
06:48jonathanjis it possible to attach a listener that is executed when a future is realized?
06:49jonathanjderef-ing a future without knowing if it's going to block or not is not ideal
06:52tdammersif you don't want it to block, then maybe a future isn't the right primitive to use?
06:55jonathanj__tdammers: what are my other options?
06:57tdammerswell, you could roll your own code using atoms and lambdas
06:58tdammersbut (realized? f) would probably fit the bill
06:58tdammersi.e., only deref the future if realized? says it's ready
07:41jonathanjtdammers: i guess the question then is what do you do if it's not realized by the time you test it?
07:43tdammersjonathanj: well, what *can* you do? fail hard, or mitigate. It depends on what you want it to do in that case
07:43jonathanjthere's a third choice: wait some more
07:43tdammersI'd file that under "mitigate"
07:44tdammersbut yeah
07:44jonathanji see manifold can coerce futures to deferreds, which means i can use (chain) add a callback
07:44tdammersanother option would be to restructure your code such that the part that blocks on the future runs in a separate thread
07:44jonathanjit's kind of annoying there isn't anything in the core library that is effectively (wait-for-this-dereffable-then-do derefable f)
07:45jonathanji suppose it's probably a lot of complexity
07:49l1xhow can i translate the chained java methods to Clojure the easiest? new StoreValue.Builder(riakObject) .withLocation(location)
07:49l1x .withOption(Option.W, new Quorum(3)).build();
07:49l1x(.something (.withOption ....) right?
07:50l1xthere is the .. macro
07:54jonathanji think: (.. (StoreValue.Builder. riakObject) (withLocation location) (withOption Option/W (Quorum. 3) build)
07:54l1xnice!
07:54l1xthanks jonathanj
07:54jonathanji missed a ) before the last build
07:55l1xisnt StoreValue.Builder supposed to be StoreValue/Builder?
07:55jonathanji don't know, possibly, it kind of depends on what it is
07:56jonathanjif it's a static, then yes
07:56l1xthank you
07:56jonathanjif it's an inner class then it gets a bit hairier
07:57jonathanji think you basically turn the . into $ for inner classes
07:57jonathanjhttp://blog.jayfields.com/2011/01/clojure-using-java-inner-classes.html
07:57l1xhuh, never done that
07:58l1xi am trying out
08:00jonathanjfrom the docs, it looks like it is an inner class
08:00jonathanjso you need to import StoreValue$Builder and address it like that
08:07l1xhttps://gist.github.com/l1x/f78b129367a1a6ce80b3
08:07l1xlike this?
08:08jonathanjyes
08:09l1xcool now i need to figure out how to chain them
08:10l1x store (.build (.withLocation riak-location (StoreValue/Builder. riak-object)))
08:10l1xsomething like that
08:10jonathanjthe name is StoreValue$Builder
08:10l1xthis works -> (StoreValue$Builder. riak-object)
08:11jonathanjyou can use .. to pull that structure inside out
08:11l1xyes
08:12l1x(.withLocation (StoreValue$Builder. riak-object) riak-location)
08:12l1xthis also works
08:12yendaDoes it make sense if I have a clojure app to build a cljs interface for it ?
08:12l1xjonathanj: yeah
08:14jonathanji'm assuming withLocation mutates the object and returns `this`, in which case (doto) might also be useful
08:15gfredericksdoto doesn't need the object to be returned
08:15gfredericksmethods that return `this` can be used with ->
08:16jonathanjwhat i meant was: since the return value is always the same object you can use doto instead of .. to chain the calls
08:16l1xhttps://basho.github.io/riak-java-client/2.0.0/com/basho/riak/client/api/commands/kv/StoreValue.Option.html
08:16jonathanjwhich gives you a bit more flexibility because if you have something that is not part of a chained call, you can put it in your (doto) form, whereas with (..) you need to start a new form
08:17l1xi guess i need to import this
08:17l1xwith the $ way
08:17jonathanjgfredericks: my experience with Java interop is that -> is not often useful because the order of the arguments wobbles around a lot
08:18jonathanjbut i guess those chained calls would work perfectly well
08:22ridcullyalso doto would not return the build-result, but the builder?
08:24jonathanjyeah, that's true
08:24jonathanjhow the heck does (is (thrown? ...)) work?
08:25lumait's magic
08:25jonathanji went looking for a function `thrown?` and found nothing, then read the docs for clojure.test
08:26l1xjonathanj: thank you very much for your help
08:26l1xit works! :)
08:26l1xhttps://gist.github.com/l1x/f78b129367a1a6ce80b3
08:26lumathe is-macro checks if the first item of the list is 'thrown?, and acts accordingly if it is
08:26l1xdo you think I should rewrite it using the .. ?
08:26jonathanjhow do i use thrown? with ex-info?
08:27jonathanjl1x: or -> like gfredericks suggested
08:27lumawell, the only thing you can check is if an exception of a specific class is thrown
08:27lumaor specific class and message with thrown-with-msg?
08:27jonathanjluma: yeah... (ex-info) kind of hides that from me
08:28lumaex-info creates an exception of class ExceptionInfo, you can check for that
08:28jonathanjcan i test the info on an ex-info?
08:28lumano
08:28jonathanjso i guess i write my own (try)
08:29lumaor yes, but then you have to manually catch it with (try ... (catch ExceptionInfo ex ...))
08:30jonathanji think maybe it's time to use midje
08:31l1xthanks
08:32jonathanjl1x: :)
08:45BRODUSany ideas why this simple try catch block isn't working
08:45BRODUS(try (keys [1 2 3]) (catch Exception e (println "error")))
08:45opqdonut,(keys [1 2 3])
08:45clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry>
08:45BRODUSright, I expect it to fail
08:46opqdonutI just checked what the exception is
08:46opqdonutan Error wouldn't get caught, but it's an Exception
08:46beaky,(try (keys [1 2 3]) (catch Exception e (0)))
08:46clojurebotbeaky: I don't understand.
08:46beaky:(
08:47opqdonut(0) is wrong anyway
08:47beaky,(try (keys [1 2 3]) (catch Exception e (nil))))
08:47clojurebotbeaky: Cool story bro.
08:47BRODUSCaused by java.lang.IllegalArgumentException
08:47BRODUS Can't call nil
08:47opqdonutbeaky: you have one ) too much
08:48opqdonutBRODUS: very interesting
08:48opqdonutit indeed doesn't work
08:48ARM9contemplate why (nil) is erronous
08:49opqdonutBRODUS: ah, I know, keys returns a lazy sequence!
08:50opqdonutfor some reason (doall (keys [1 2 3])) doesn't help though
08:50opqdonutbut e.g. (first (keys [1 2 3])) does work
08:50opqdonut,(try (first (keys [1 2 3])) (catch Throwable e :error))
08:50clojurebotopqdonut: I don't understand.
08:50BRODUSi understand lazy sequences mostly, but its not clear why thats the reason its failing
08:50opqdonutclojurebot has probably banned try-catch
08:51lumabecause it's a lazy sequence, the error isn't thrown inside the try
08:51opqdonutthe error is thrown when somebody tries to use the result
08:51lumathe lazy sequence is returned out of the try, and the error is thrown when that lazy sequence is later realized
08:51opqdonut,(do (keys [1 2 3]) 1)
08:51clojurebot1
08:51opqdonutsee, no error
08:52opqdonut,(do (first (keys [1 2 3])) 1)
08:52clojurebot#error {\n :cause "java.lang.Long cannot be cast to java.util.Map$Entry"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to java.util.Map$Entry"\n :at [clojure.lang.APersistentMap$KeySeq first "APersistentMap.java" 166]}]\n :trace\n [[clojure.lang.APersistentMap$KeySeq first "APersistentMap.java" 166]\n [clojure.lang.RT first "RT.java" 660]\n [clojure....
08:52opqdonut,(do (doall (keys [1 2 3])) 1) -- I have no idea why this doesn't break though
08:52clojurebot1
08:54MJB47doall is only used for side effects
08:54MJB47it returns nill iirc
08:54MJB47while first returns the value
08:54opqdonutMJB47: doall should still realise the sequence and give me the error
08:55opqdonut,(doall (map #(/ % 0) [1 2 3])) -- e.g.
08:55clojurebot#error {\n :cause "Divide by zero"\n :via\n [{:type java.lang.ArithmeticException\n :message "Divide by zero"\n :at [clojure.lang.Numbers divide "Numbers.java" 158]}]\n :trace\n [[clojure.lang.Numbers divide "Numbers.java" 158]\n [clojure.lang.Numbers divide "Numbers.java" 3788]\n [sandbox$eval122$fn__123 invoke "NO_SOURCE_FILE" 0]\n [clojure.core$map$fn__4541 invoke "core.clj" 2625]\n [cl...
08:55opqdonut,(do (map #(/ % 0) [1 2 3]) 1) -- for comparison
08:55clojurebot1
08:56lumaopqdonut: it's because of how keys works
08:56lumadorun/doall just continuously calls next on the sequence
08:57lumaand KeySeq (which is what implements keys) only actually produces the key when first is called on it
08:57opqdonutbut clojure sequences are only lazy in the spine, not the values
08:57lumanot when next is called on it
08:57opqdonutoh, KeySeq is special
08:57opqdonutbah
08:57lumahttps://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/APersistentMap.java#L165-L171
08:58opqdonutthanks
08:58yendaIs it possible to have a clojurescript frontend for a clojure program ? is there something simpler than using ring to make them talk to each other ?
08:59dnolenyenda: yes. I can't think of anything much simpler than ring etc.
09:01BRODUSthanks for the help everyone
09:04jonathanjluma: how do actually address ExceptionInfo?
09:05jonathanjclojure.lang.ExceptionInfo it seems
09:07yendadnolen: so ring+compojure is the way to go ?
09:07j-pbyenda: bidi is nicer when you do cljs as well
09:08j-pbit allows you to share routes between cljs and clj and generate urls from those shared datastructures
09:08j-pbit's much more declarative than compojure
09:08j-pbyou can also use a websocket, if you want more real live communication between your ab and it's ui
09:09j-pbbut then you are more constrained in terms of browser support
09:09yendaj-pb: Browser support is not a problem
09:11j-pbsetting up a websocket connection is not that hard to do, and it's somewhat nicer than posts
09:11j-pbI'd pick something like sente for that
09:12dnolenyenda: there is no "way to go"
09:12dnolenbut yes that will work
09:13poweredyou still need ring for Sente
09:14j-pbpowered: yeah true, but it's a lot less exposed
09:14poweredtrue
09:14yendaj-pb: I'm not sure I need websockets though
09:15yendaI just need to call functions that alter structures or have side effects and return results
09:15poweredif you don't want low latency or server -> client messages then don't use websockets
09:19yendapowered: sente could be nice to watch components state I could add it later
09:19yendapowered: but for now I just want to have a UI to call functions and move stuff in a graph and send it back again to other functions
09:20poweredright so you need a simple and quick middleware setup?
09:20poweredsente's good for that too
09:23yendapowered: ok, I settled for om frontend-wise so I'm gonna see how it fits with sente
09:24jonathanjif the body of a (future) throws, that exception is wrapped in ExecutionException, is it possible to not do that?
09:28j-pbjonathanj: you could catch the exception within the future
09:42QU35tFellas
09:42opqdonutjonathanj: or you can just unwrap it when forcing the future
09:48jonathanjj-pb: i actually want the exception though
09:48jonathanjopqdonut: yeah, that's a little bit inconvenient since i'm writing tests for something that returns a future
09:49jonathanjon another note, does anyone use cider and midje together? i can't really seem to get the cider test running stuff working with midje
09:58heero_Hi, is there a function to reduce over multiple coll ?
09:59heero_(reduce coll init list1 list2 ...)
10:00j-pbheero_: (reduce fn init (map vector col1 col2 col3 ...)) ?
10:00powered(remove even? {:a 1 :b 2 :c 3})
10:01poweredwhat is the function I'm looking for instead of remove ?
10:02j-pbpowered: clojure had something like that as a contrib library
10:02heero_j-pb: ok thx
10:04MJB47wouldnt filter work?
10:05MJB47,(filter #(even? (second %)) {:a 1 :b 2 :c 3})
10:05poweredthis works: (remove #(even? (second %)) {:a 1 :b 2 :c 3})
10:05clojurebot([:b 2])
10:05poweredah yes
10:06j-pb,(remove (comp even? val) {:a 1 :b 2 :c 3})
10:06clojurebot([:a 1] [:c 3])
10:09j-pb(apply into ((juxt empty (partial remove (comp even? val))) {:a 1 :b 2 :c 3})
10:09j-pb,(apply into ((juxt empty (partial remove (comp even? val))) {:a 1 :b 2 :c 3})
10:09clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
10:09j-pb,(apply into ((juxt empty (partial remove (comp even? val))) {:a 1 :b 2 :c 3}))
10:09clojurebot{:a 1, :c 3}
10:09j-pbsrcr
10:10j-pbscnr lol
10:21kungiHow do I do an &nbsp in hiccup?
10:22kunginevermind I found "&nbsp;" :-)
11:03visofhi guys
11:15sdegutisI don't know why I signed onto IRC and into #clojure. It was just habit I guess.
11:15sdegutisSo.. um.... hi?
11:20Shambles_sdegutis: Hi.
11:20sdegutisHi.
11:20sdegutisI take it justin_smith is asleep then?
11:28Shambles_sdegutis: I have no idea.
11:28sdegutis:)
11:38WorldsEndlessSo, I thought the doseq family of functions ran only as long as the shortest supplied vector, but was proved wrong by(doseq [n (increment 1) v [\a \b \c]] (println n v))
11:38j-pbdoseeq is like for
11:39j-pbso if you have
11:39WorldsEndlessSo what if I just want to assign a number to each item of another thing (i.e. for file output)
11:39j-pb(map vector col (range))
11:39j-pbor (map-indexed vector col)
11:39j-pbI prefer the first, but others would probably disagree
11:40j-pb,(map vector [:a :b :c] (range))
11:40clojurebot([:a 0] [:b 1] [:c 2])
11:40j-pblike this?
11:40WorldsEndlessI guess with the latter, I'd then be able to extract the index with something like (doseq [[n v] indexed-vector]) ?
11:40j-pbwhy do you want to do that?
11:40j-pbyes, but
11:41j-pbyou can force lazy evaluation, with dorun and doall :)
11:41WorldsEndlessj-pb: Ah, map is the one that truncates on teh shortest, not the comprehensions. Ok
11:41j-pbyeah
11:41j-pbthe comprehensions will walk sequences later provided for each element before
11:42j-pb,(for [x (range 3) y (range 3) z (range 3)] [x y z])
11:42clojurebot([0 0 0] [0 0 1] [0 0 2] [0 1 0] [0 1 1] ...)
11:42j-pb,(for [x (range 2) y (range 2) z (range 2)] [x y z])
11:42clojurebot([0 0 0] [0 0 1] [0 1 0] [0 1 1] [1 0 0] ...)
11:44WorldsEndlessSo with the comprehensions, I should avoid infinite sequences, or just position them later?
11:45WorldsEndlessrightwards, that is
11:45j-pbwith doseq don't do infinite sequences
11:45j-pbbeause it's eager
11:46WorldsEndlessI'm guessing that as long as you respect the laziness, (for) should be okay?
11:46j-pbwith for, you can happily have infinite sequences, but if you have one nothing before it will advance
11:46j-pbyeah
11:46j-pb,(for [x (range) y (range 2)] [x y])
11:46clojurebot([0 0] [0 1] [1 0] [1 1] [2 0] ...)
11:46j-pbhowever
11:46j-pb,(for [x (range 2) y (range)] [x y])
11:46clojurebot([0 0] [0 1] [0 2] [0 3] [0 4] ...)
11:47WorldsEndlessCool. I'm still not as fluent as I would like to be in laziness
11:47j-pbyou might as well had written
11:47j-pb,(for [x [0] y (range)] [x y])
11:47clojurebot([0 0] [0 1] [0 2] [0 3] [0 4] ...)
11:47j-pbbecause it will never get passed the first element
12:22WorldsEndlessregexp aren't behaving as I expect. Why is #"^" not matching "beginning of line"?
12:23ridcully,(re-seq #"(?m)^\w" "a b c\nd e f")
12:23clojurebot("a" "d")
12:24WorldsEndlessooh. ?m is new to me
12:24WorldsEndlessis there a doc page for that (googling for regexps is hair-whitening)?
12:25lumaWorldsEndless, http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
12:25justin_smithWorldsEndless: all the (?*) flags are documented in the javadocs
12:25justin_smithor what luma said
12:27WorldsEndlessbeautiful. That link will come in handy, too. Thanks.
12:42WorldsEndlessbasic (probably java) question here: I have a dir-path string (not file). If it doesn't exist, I need to create the file. make-parents doesn't seem to do the trick, since it's a dir. What function do I need here?
12:44WorldsEndlessAh. Files.createDirectory
12:45WorldsEndlessI learn much more of Java from working in Clojure than I did in years of classes in Java...
13:15yendahaha same for me
13:16yendaand I learned more of Clojure in 3 months than in java in 3 years
13:40ecmikeUse Clojure to learn Java, use Java to learn Boilerplate
14:15tolstoyLearn Clojure to have fun at home, and Java to have someone else decide what and when to do a job-jar task based on a 10-year-old outdated architecture.
14:15tolstoy"For 15 years we've known inheritance is a bad way to model your domain." Scribbles: Not a team player. Doesn't get Agile.
14:15tolstoyDoesn't understand "the business".
14:15tolstoy</rant>
14:16tolstoyMore positively: I wonder if there's a place for a "lein" like script that uberjars up clojure + that fs library for scripting (if you don't mind slow JVM start up, which I don't).
14:23justin_smithtolstoy: it's not the jvm that is slow to start up, it's clojure
14:24tolstoyI've got a "clj" script that starts up the repl. Plenty fast for me. I'd love something with some extra file-system utils.
14:25justin_smithsure, make a project with the right deps, uberjar, then you can do "java -cp your.jar clojure.main" to get a repl
14:25justin_smithyou don't even need any main ns or aot for that to work
14:25tolstoyRight!
14:25justin_smithfor bonus points put pomegranate in there too, so that maven deps can be pulled in at runtime
14:26justin_smith(if you really need them)
14:26tolstoyExactly. You can have the "mh" of build systems.
14:26justin_smithheh
14:26alive876hi newbie here, i have a project that "lein run" works "lein test" ok , but when i run "lein repl" i get Var null/null is unbound. the project file and main file are http://pastebin.com/2pWGAP0u and http://pastebin.com/Pn721weh thanks much
14:27tolstoyA simple app to build a classpath. Another app to run a repl. Then just compose them. No complicated "boot" thing. ;)
14:28tolstoyReally, all you need is something to resolve deps and the rest: bash (or whatever).
14:28tolstoyHm. How do you get the org mode manual inside an emacs buffer? I don't know how to work the help system.
14:28justin_smithalive876: I don't know noir but :ns 'jcrit is suspicious - there is no ns called jcrit there
14:29justin_smithtolstoy: M-x info
14:29alive876ok , ty
14:29tolstoyjustin_smith Thanks!
14:29justin_smithtolstoy: after that you can click the hyperlinks or nav via keyboard
14:30justin_smithtolstoy: info is pretty cool - for example incremental search will look into subchapters that aren't visible in the buffer
14:30justin_smithand using org, you can create followable links to places in the info system!
14:30justin_smith(full circle)
14:31tolstoyjustin_smith: That's great. I always need to look up in buffer options.
14:31alive876(ns jcrit.server
14:33justin_smithalive876: right, I was referring to the args to the noir server start. Also, just fyi lib-noir is still maintained, but noir itself is deprecated and they recommend using ring + your routing lib of choice directly
14:34alive876ok thanks
14:35tolstoyHm. I always have `:main ^:skip-aot foo.bar`. I wonder if that metadata tag is even needed anymore?
14:35alive876but for my edification , this does or doesn't create the jcrit ns?
14:35alive876i mean (ns jcrit.server
14:35justin_smithalive876: no, it creates the jcrit.server ns
14:36alive876ok,thanks
14:36tolstoyalive876 Try commenting out the (server/load-views ...) form and see if that fixes it.
14:36rhg135tolstoy: AFAIK not till lein 3
14:37rhg135For now aot is the default for main
14:37tolstoyrhg135: Ah. I've been including that so long, the problem it solved for me has receded into the dim mists of time.
14:37justin_smithbut if your jar / uberjar isn't meant to be a point click run app, you don't need a :main-ns
14:39rhg135Yeah, I guess the maintainers assumed lein 3 would come soon
14:40rhg135The bug report is old
14:41alive876<justin_smith> that doesn't seem to work. and at the beginning i keep getting this too:Consider using [enlive "1.0.0" :exclusions [org.clojure/clojure]].
14:46justin_smithalive876: that's a separate issue - you are using an old version of enlive which asks for a different version of clojure than your other libs
14:46justin_smithnoir probably asks for some ancient version of clojure like 1.3 or something
14:47alive876it seems a lot of broken tutorials out there
14:47justin_smithalive876: yeah, clojure moves a little faster than the google magic that would lead you to the up to date stuff
14:49justin_smithbut that's just a warning, the real issue is that noir isn't being started up properly. As I mentioned that 'jcrit arg is pointing it to a namespace that doesn't exist, but what does noir actually want that namespace to be, or to have in it?
14:50alive876yea, i just looked and the tutorial is 4 years old
14:50justin_smithmaybe you could find a newer tutorial, maybe one using bidi or compojure instead of noir
14:56princesois there a function to map data like this {:a 1 :b 2} into some complex object like {:c :a :d {:e :a :f :b} } to result in {:c 1 :d {:e 1 :f 2}} ?
14:57ecmiketolstoy: just saw your rant, spot on
14:57clojurebotHuh?
14:58justin_smithprinceso: what is the relationship between the inputs and outputs there?
14:58justin_smithis it just mapping the vals by your {:a 1 :b 2} ?
14:59princesojustin_smith yes
14:59justin_smith,(require 'clojure.walk)
14:59clojurebotnil
15:00justin_smith,(clojure.walk/postwalk (fn [o] (if (map? o) (into {} (map (fn [k v] [k ({:a 0 :b 1} v v)]) o)) o)) {:c :a :d {:e :a :f :b} })
15:00clojurebot#error {\n :cause "Wrong number of args (1) passed to: sandbox/eval49/fn--50/fn--51"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: sandbox/eval49/fn--50/fn--51"\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" 32]\n [clojure.core$map$fn__4541 invok...
15:00justin_smithoops
15:00justin_smith,(clojure.walk/postwalk (fn [o] (if (map? o) (into {} (map (fn [[k v]] [k ({:a 0 :b 1} v v)]) o)) o)) {:c :a :d {:e :a :f :b} })
15:00clojurebot{:c 0, :d {:e 0, :f 1}}
15:01justin_smith,(clojure.walk/postwalk (fn [o] (if (map? o) (into {} (map (fn [[k v]] [k ({:a 1 :b 2} v v)]) o)) o)) {:c :a :d {:e :a :f :b} })
15:01clojurebot{:c 1, :d {:e 1, :f 2}}
15:01princesoomg you rock justin_smith! thanks
15:01justin_smithprinceso: of course you could name things and make it not a one-liner
15:03justin_smiththe main tricks there are using postwalk in order to do nested updates, using into {} in order to map over a hash-map and create a new hash-map, and the usage of the hash-map as a lookup function (with the optional not-found value, so that the nested hash-map stil comes through))
15:03justin_smithand the key/value destructuring from the map entry tuple
15:04ecmikejustin_smith: that's really great... do you have any suggestions for learning clojure that well? I find myself doing a lot of thrashing before getting to anything elegant like that
15:04justin_smithecmike: hanging out here and trying to read / recreate /improve the one-liners helps :)
15:05justin_smithecmike: also, there is of course http://conj.io as a reference, and seeing other people's answers on 4clojure
15:05ecmikejustin_smith: doing that already, wondering if there were any books/sites/etc you recommend
15:05ecmikejustin_smith: oh great, I'll check that out
15:05princesojustin_smith: thanks for that. am almost new to clojure, so ill figure out how it all works.
15:05ecmikebookmark*2
15:06justin_smithprinceso: as I recommended to ecmike above, conj.io helps - as does the community knowledge here in the channel if you try to follow the discussion
16:07WorldsEndlessI am segmenting a file into many files based on a regexp; it works if I slurp and use string/split, but this will have problems for large files. How can I make this large-file friendly?
16:09WorldsEndlessIs the best way to iterate through the lineseq and check for re-match, and then split and send the splits to the appropriate place?
16:15jonathanji see people talking about using nrepl in production to embed a repl for investigation etc. purposes
16:15jonathanjhow do you prevent any random person from connecting to your repl?
16:15justin_smithWorldsEndless: that seems reasonable, yeah, though you could try variations like reading N bytes followed by cleaning up the odds and ends by combining any left over from the previous (if any) before running the regex
16:16justin_smithjonathanj: by default nrepl only allows connections from localhost (which is a good idea), and then you need to use an ssh tunnel to use it from another host
16:16jonathanjah
16:17jonathanjany reason not to embed an nrepl in a production server?
16:17justin_smithmemory overhead I guess - nrepl is pretty easy to launch from an app
16:18celwelljonathanj: that's a terrifying sentence. what's the reason, just curious.
16:18justin_smithcelwell: well we already discussed the fact that it won't be available without a secure connection
16:27TimMccelwell: It is both terrifying and incredibly usful.
16:28TimMcjonathanj: We use liverepl instead. The protection is that you have to be the same user who launched the JVM process in order to inject the agent.
16:28TimMcI once tried to add nrepl to an app using drawbridge but I couldn't get password protection working.
16:29justin_smithTimMc: my take was that realistically every OS has local holes, and the realistic barrier to enforce is logged in / not logged in, and once logged in you can't prevent escalations
16:30justin_smith(though I guess they don't always have to be as easy as they are via nrepl)
16:31TimMcYeah, but there's always a *chance* your kernel is up to date. ;-)
16:31TimMcHeck, if you're inside the datacenter at most shops you're probably as good as in.
16:31justin_smithTimMc: kernel, plus userland - there are local exploits via games, random file conversion utilities, libraries...
16:50TimMcjonathanj: One downside of liverepl is that it doesn't give you all the nice nrepl features, you just get a raw repl with no line-editing.
16:50TimMcliverepl can load additional jars, so that might be a path through if that's a problem for you
17:06jonathanj__TimMc, justin_smith: Thanks for the discussion, I'll do some reading.
17:13glosoliHey what's the name of the some tool that could scan through the project and point out the stuff that is being done unconventionally ?
17:13celwellkibit
17:13justin_smitheastwood is good for this too
17:15glosolithanks
18:22irctcHi everyone! :)
18:23WorldsEndlessHi, irctc
18:23irctcI need help with a concept in functional programming paradigm. I have a function that connects to an API and returns an xml file. Then I need to parse that file, extract info from the parsed result, do some calculations etc, etc. Now I want to make my code functionally as pure as possible.
18:24irctcAs things stand now I have a sequential stack of calls that goes all the way back to the connection that relys on each function passing through a user ID with wich to connect to the api in the connection function.
18:24irctcHow do I change this to be more functionally pure?
18:24irctcHi WorldsEndless. :)
18:25irctcI am thinking that a more functionally pure way would be to just call this connection function once and then save the returned xml in a global (def) and then pass that def arround to other pure functions.
18:26irctcAm I right in approaching this problem that way or is there another way that it should be done?
18:26WorldsEndlessInteresting. I recently watched Stuart Sierra's talk on functional design patterns that might be of interest to you: https://www.youtube.com/watch?v=etr08mExAI0
18:27WorldsEndlessirctc: Using React-based web libraries, the global atom idea is pretty standard
18:28irctcWhat does that mean. Sorry I'm new to functional programming.
18:28WorldsEndlessirctc: Although I recently had to redo one of my codebases to pass the value around rather than look it up globally, which brought a lot of benefits
18:28tolstoyirctc I think the idea is to do all your side-effects at the front (or end), so don't bury the web request in the middle of calculations.
18:29WorldsEndlessSo, Facebook's "React" framework is a popular javascript engine that has proven very powerful in the hands of Clojurians. The clojurescript approaches, like Om or Reagent, rely heavily on that idea of a global Atom
18:29tolstoyirctc: Just make the request, then pass the result to pure transforms, then save (or whatever) the result.
18:29WorldsEndlessAgree with tolstoy
18:29irctctolstoy, my web request goes all the way through my entire algorithm. This makes it very hard to do unit testing as well.
18:30WorldsEndlessirctc: Just make the request once, as you were thinking, and pass the needed parts around to what needs them
18:30tolstoyirctc: Actually making the request is buried in there somewhere?
18:30justin_smithif you put it in a def, then you are stuck with only being able to handle one xml file, with pure handlers and no global you can process as many as your computer can handle
18:30irctcSo, the request should be made up front and then saved in a def?
18:30WorldsEndlessirctc: you may not need to save it in a def at all
18:30irctcOk, so how do I go about that aproach?
18:31justin_smithirctc: how many different xml files would you ever handle? if it's exactly one for the entire lifetime of the app a def may be OK, if you would ever need a second xml file, definitely don't use a def
18:31tolstoyirctc: Using a "def" is just an implemenation detail. You could: (let [xml (make-request...)] (save-to-db (transform xml))). No global.
18:31irctc>=1
18:31irctcNah, I don't use a db here.
18:31justin_smithyeah, if 2 would ever happen, a def would just make things more complicated
18:32irctcI agree justin_smith. You have a point there.
18:32tolstoyirctc: Again, it's just to illustrate that the network retrieval and saving are at the top level, not in the `transform` bit.
18:32WorldsEndlessSo, guys, I'm a bit tangled up on an idea. Spliting one file to many using readers and writers, I open with "with-open [reader ..]" but am not sure how to alternate writing to a current file with writing to a new file when I match my break-regex.
18:33irctcSo when I do (connection userid) where userid is some number like 123, I get my xml file back. How do I then pass it to pure functions without calling (connection userid) function from other functions?
18:33justin_smithThe functional concept is that a function given the same args should return the same result. So focus on breaking the task up to stages that are 100% dependent on their arguments.
18:34justin_smithirctc: by calling those functions
18:34tolstoyirctc: (let [xml (connection userid)] (transform xml))
18:34justin_smithWorldsEndless: with loop or reduce you can have a binding that is passed for each item, and when you see that a new output file is needed you pass that along as the new binding
18:35WorldsEndlessWait... you can do that with reduce?
18:35irctcOk, the way I have it set up now is I make (top-function-call userid) --calls--> (mid-function-call userid) --calls--> (bottom-function-call userid) --calls--> (connection userid).
18:35justin_smithWorldsEndless: something like (reduce (fn [[out-file acc] el] ... [new-out-file new-acc) lines)
18:35tolstoyWorldsEndless: Hm. You could use a multimethod? read-line, charaterize it, then pass it to a multimethod, even method of which knows which file to append it to?
18:36justin_smithWorldsEndless: the idea being on a given line you know whether to make a new file or not, and that's the file you pass to the processing of the next line
18:36tolstoyirctc: Right. I'd reverse that, if you can. Then pass the XML through your other functions as needed.
18:36irctctolstoy, you mean I should do a let [xml (connection userid)] at the top-level-function and then just pass the local xml binding to other calls within the top-level-function?
18:37tolstoyirctc: Yes.
18:38irctctolstoy, I think that makes sense. :) Thank you.
18:38tolstoyirctc: At least one benefit of that is that when you read each function, the only thing that function can see are the params.
18:38irctcThank you everyone for your help. I'm gona try it this way.
18:38WorldsEndlessirctc: good luck
18:39irctcWell the main benefit for me will be that I'll be able to do unit testing. Right now I would have to rely on an external api call and that's a real mess if you have large xml files.
18:39irctcPlus debugging is much easier with pure functions.
18:40tolstoyirctc: Yes!
18:40irctcI think imperative languages have broken me from the start. lol
18:41justin_smithirctc: pure functions are just imperative functions that are only allowed to use data that is in the arg list and can only change things that they return
18:41justin_smithyou end up returning collections more often, for this reason
18:48irctcjustin_smith: I feel that because of the lessons I learned while using clojure this made me a better imperative programmer. The notion of pure functions is just not enforced that much from the get go in imperative paradigm. I actually wish I was taught a functional language first before imperative languages.
18:49justin_smithirctc: only using arg lists and returning data instead of modifying it are good default behaviors for sure
19:45domgetterSo I'm trying to take advantage of the JVM doing optimizations, and I'm using dotimes to see timing from multiple runs of a function. Within a dotimes call, I can see it taking less and less time, but a second call to dotimes starts everything over. Is there a way to keep what "work" the JVM did? https://gist.github.com/domgetter/8c0f66b58cbeca135731
19:46domgetterAs you can see on lines 69, 196, and 1310, the times drop.
19:47domgetterWhen I call dotimes a second time, is it starting over because I'm in a repl?
19:48domgetterOr (depending on the optimization of course) can I expect an optimization to stick around in production?
20:02BRODUSsay i have a complicated expression, and I want to check if the result is either nil? or seq?, how I could I write that while only writing the expression once
20:03BRODUSrather than writing it twice in the or expression
20:04lambda-11235(let [val ...] (or (nil? val) (seq? val))
20:42codahaledomgetter: If you’re trying to benchmark something, I’d suggest using Criterium. The JVM makes naive benchmarking effectively impossible.
21:36jghasjhjkasdhi can someone tell me why this doesn't work? (map #(1) [1, 2, 3])
21:36jghasjhjkasdjust trying to turn the list in to a list of 1's
21:36justin_smith,'#(1)
21:36clojurebot(fn* [] (1))
21:37justin_smiththat tries to call 1 as a function
21:37jghasjhjkasdohh right ok
21:37justin_smith,(map (constantly 1) [1, 2, 3])
21:37clojurebot(1 1 1)
21:37justin_smith,(map (fn [_] 1) [1, 2, 3])
21:37clojurebot(1 1 1)
21:38justin_smithmy two minor peeves about clojure is that identity is longer than (fn [x] x) and constantly is longer than (fn [& _] x)
21:41lambda-11235justin_smith: Indeed, I find myself defining id and const in the REPL when I need them.
21:42lambda-11235identity is still two characters shorter than (fn [x] x).
21:44justin_smithlambda-11235: oh right, (fn[x]x) isn't nearly as nice
21:47jghasjhjkasdhey justin_smith
21:48justin_smithyes?
21:48jghasjhjkasdis there any way to do that map thing with the shorthand syntax?
21:48jghasjhjkasd(map (fn [_] 1) [1, 2, 3])
21:48jghasjhjkasdwith #
21:48justin_smiththe closest you can get is #(do % 1)
21:48justin_smithbecause otherwise it will complain about the arg count
21:48justin_smithand #(do % 1) is terrible
21:49jghasjhjkasdi dont get it.. why do you have to use all the arguments?
21:49justin_smithjghasjhjkasd: because if you don't use any args, the compiler generates a function that takes no args
21:49justin_smithand you get an error because you get an arg
21:49BRODUSis there a function that returns the maps a predicate to a collection and returns the first value that satisfies the predicate?
21:49jghasjhjkasdoh ok
21:49jghasjhjkasdthx
21:50BRODUS*is there a function that maps a predicate to a collection and returns the first value that satisfies the predicate?
21:50justin_smithBRODUS: (comp first filter)
21:50justin_smith,((comp first filter) even? [1 3 6 42])
21:50clojurebot6
21:50BRODUSthat makes sense
21:54BRODUSand because filter returns a lazy sequence that means it will not map over the whole collection
21:57justin_smithright
21:58justin_smithbut I still find it surprising there isn't a function for "first item matching the predicate" built in
22:14amalloythat obvious missing function is rich's subtle way of encouraging everyone to run their own fork of clojure with noe added function
23:33tolstoyBRODUS "some" kinda does that. (some #(when (pred? %) %) coll).
23:33BRODUSright but that just returns a boolean
23:34tolstoyThe way I wrote it there, it returns the value.
23:34BRODUSoh i see
23:34tolstoy,(some #(when (even %) %) [1 3 5 6 8 1 2 4])
23:34clojurebot#error {\n :cause "Unable to resolve symbol: even in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: even in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: even in this co...
23:34tolstoy,(some #(when (even? %) %) [1 3 5 6 8 1 2 4])
23:34clojurebot6
23:37BRODUSgood to know, i need to use 'when' more
23:37tolstoyPart of the when, when-not, when-let family.
23:50jghasjhjkasdhow do you remember when the list/collection is the first or last parameter of clojure functions? just memorization or is there logic behind it?
23:51jghasjhjkasdlike cons is list last, conj is list first, nth is list first, reduce is list last, etc.
23:52tolstoyMy guess: if it's operating over a range of values, it's at the end (map, reduce, etc).
23:52tolstoyBut if you're just changing one thing about the collection, it's first (conj, assoc).
23:54amalloyjghasjhjkasd: mostly things that operate on sequences take them last, where things that operate on any kind of collection take it first
23:54amalloyalso how do you remember your username
23:54jghasjhjkasdi just typed in a bunch of gibberish it's not my username i'm using irc web client