#clojure logs

2015-08-20

02:49mdallastella'morning
03:40OlajydHi, TEttinger
03:43TEttingerhey Olajyd
03:44OlajydGreat to have you around
03:45OlajydTEtinger say given a date string, I want to be able to add days to it, I’m kinda lost on how to go about it
03:47OlajydTEtinger, some of the use cases: 365 will add one year, -7 will subtract one week. 0.5 will add half a day, and 0.04 will add a little less than one hour (57 minutes and 36 seconds).
03:48KneivaOlajyd: https://github.com/clj-time/clj-time
03:49Olajydaite Kneiva
03:54Olajyd_Kneiva, what should i bee lookiing for
03:56KneivaOlajyd_: that's a clojure wrapper to yoda time library, that does pretty much what you want: manipulate dates and times
03:56Kneiva(t/plus (t/date-time 1986 10 14) (t/months 1) (t/weeks 3))
03:56Kneiva=> #<DateTime 1986-12-05T00:00:00.000Z>
03:59Olajydhmmm Kneiva, say the date sting is 2014-05-12 Do I have to split the string to be in the form of “2014 05 12”
04:01TEttinger(inc Kneiva)
04:02OlajydKneiva: or parse the date string
04:05TEttingerOlajyd: clj-time.format has what you need I think.
04:05TEttinger(formatter "yyyy-MM-dd")
04:06TEttingershould be the format you want, if it's month then day
04:06gilliardIf that's May 12th then the built-in formatter will get it.
04:07gilliard,(clj-time.format/parse "2012-05-12")
04:07clojurebot#error {\n :cause "clj-time.format"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clj-time.format"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java...
04:08OlajydI’m assuming that the format is going to be in "2012-05-12" format
04:08gilliardIf the "05" is the month part (not the day-of-month) then that's iso8601 format so the default parser will work without a custom format.
04:16TEttingeroh nice
04:31OlajydSo what do you think?
04:31Olajydsorry I got disconnected from the rom for a while
04:31Olajyd*room
04:32OlajydTEttinger, any other suggestions
04:33TEttingerOlajyd: I think gilliard is right on here. 05 is may, right? and 12 is the 12th day?
04:33OlajydYes exactly
04:33TEttingeryeah then the code gilliard gave should work just fine: (clj-time.format/parse "2012-05-12")
04:34TEttingerwith a dependency on clj-time in your project.clj
04:34OlajydTEtitinger, ok
04:34Olajydwhat else
04:34gilliardWorks for me (tm) - I suppose clojurebot is missing that dependency
04:34Olajydok
04:34Olajydand work with Kneiva, solutions right?
04:35Olajyd*solution
04:35TEttingeryeah, that should give you a date in the clj-time format, you should be able to use Kneiva's suggestions just fine
04:35Olajydok
04:35TEttingerKneiva had required clj-time as t
04:35OlajydThanks
04:35TEttinger(inc Kneiva)
04:35TEttingerlazybot is down again :)
04:38gilliardOoh - can we require stuff into clojurebot? Or is that Kneiva-only?
04:39OlajydKneiva, where art thou?
04:40Olajyd:)
04:46Kneivagilliard: My example was just a copy paste from the library readme.
04:46KneivaDoes clojurebot support requiring stuff on the fly?
04:49amalloyKneiva: try it and see
04:56gilliard,(require '[clj-time.format :as f])
04:56clojurebot#error {\n :cause "Could not locate clj_time/format__init.class or clj_time/format.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name."\n :via\n [{:type java.io.FileNotFoundException\n :message "Could not locate clj_time/format__init.class or clj_time/format.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure ...
04:56Kneivacould not get it to require anything
04:58amalloyit won't dynamically go and download jars off the internet for you. but neither will any clojure repl; you'd need to change your project.clj to get lein to pre-download that stuff before starting your program
04:59amalloyanything that is actually on the classpath, clojurebot will require, eg (require '[clojure.string :as s])
04:59gilliard,(t/in-hours (t/days 1)) ; good
04:59clojurebot#error {\n :cause "No such namespace: t"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such namespace: t, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "No such namespace: t"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n :trace...
05:02Kneivaamalloy: Using this would make it possible I guess: https://github.com/cemerick/pomegranate
06:53OlajydHI
06:55OlajydI want to add 0.4 days to a particular clojure date which is equivalnent to (57 minutes and 36 seconds). I tried (t/plus (tf/parse (tf/formatter "yyyy-MM-dd") date-string) (t/days d)), any suggestion as to why this is so
06:55gilliard(t/days) only takes integers
06:55Olajyd(t/plus (tf/parse (tf/formatter "yyyy-MM-dd") “2014-05-12”) (t/days 0.4))
06:56gilliardYou need to do (t/hours (* 0.4 24)) or something like that.
06:56OlajydHi, gilliard, :)
06:56Olajydhmmm
06:58Olajydgilliard, so I wan to implement the function in such a way that all that will bw passed in to the function is just date strin and the number of days
06:58Olajydforgive my typos I’m trying to get used to touch typing :)
06:59gilliardIf you need non-integer number of days, I don't think clj-time will do that. I raised https://github.com/clj-time/clj-time/issues/192 but it was closed straight away :)
07:01Olajydgilliard, you are `mjg123` that raised th issue right?
07:03gilliardyep
07:05Olajydgilliard, so what do you advise I do in such a way that it handles both days in integers (7) and floats (0.5)?
07:14TEttingerOlajyd: you could probably get the timespan of 1 day in milliseconds, which is some very large number, multiply that by 0.4, and then convert back to a datetime
07:15Olajydok
07:15OlajydTEttinger, thanks :)
07:16TEttingerI'm checking the API to see how to do that
07:16Olajydok, will really appreciate it
07:22TEttinger(clj-time.coerce/from-long (long (* 0.4 (clj-time.coerce/to-long (clj-time.core/days 1))))) ; not sure how well this works
07:23TEttingerbut that would I think get a DateTime that is basically 0.4 of a day. I don't know what would be needed to convert that to a period again
07:24TEttingergetting late here, good luck Olajyd!
07:33Olajydhahah thought as much, thanks TEttinger, catch ya tomorrow :)
07:40Olajyd,(clj-time.coerce/from-long (long (* 0.4 (clj-time.coerce/to-long (clj-time.core/days 1)))))
07:40clojurebot#error {\n :cause "clj-time.coerce"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clj-time.coerce"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java...
08:25jweissif I have a set of functions that all take a first arg foo, what's the best way to get a set of functions that close over foo (and take one less argument)? I know i could make a map of them, but then things get awkward-looking like ((:f m) bar)
08:25jweissi thought of just dynamically creating a new namespace
08:25jweissbut i have never seen that done anywhere else.
08:26jweiss(sorry what I meant earlier is "get a set of functions that close over a particular value of foo"
08:39opqdonutjweiss: how about using a dynamic var for foo and then having (with-foo [the-foo] ... (function 1 2 3) ...)
08:39opqdonutmaybe separate (function foo 1 2 3) and (function* 1 2 3) variants or something
08:44jweissopqdonut: yeah, i know i can do that, then the functions aren't functional anymore :)
08:47opqdonutthen just return a map I guess?
08:56jasonx2clojure has dynamic variables? like common lisp?
08:56jasonx2isn't that rather unfunctional?
08:59novak`What to use for Redis? I found that there is Aleph but can't find any exapmles
09:13chouserjasonx2: most variables are lexical in Clojure. Dynamic ones are available, and yes that's not very functional in the modern sense of the word.
09:27pepijndevosIs rand-nth constant time for vectors?
09:30gilliardIt's the same as element access time which is O(log32 N), which is often referred to as effectively constant time.
09:31gilliard(same as nth)
10:50futuroIs there a general preference for private functions and defs in clojure?
10:51futuroso far I've used the non-private versions, but I've seen the private ones pop up here and there
10:52stuartsierrafuturo: private defs are basically a form of documentation: "This is not a public API, don't call it from other namespaces"
10:53futuroSo clojure doesn't stop you from using or importing private defs?
10:58stuartsierrafuturo: The compiler will throw an error if you try to call a private function from another namespace, but you can always work around it with the var-hack: @#'the-namespace/the-var
10:59futuroneat. That's good to know if I ever need that.
10:59futuroThank you for the clarification
11:01stuartsierrayou're welcome
11:16pflanzeIs there a function that takes two (or n) lists, and compares all items in them with a given comparison function, and returns true if the comparison function returned true for all elements and both lists are of the same length? (Stopping early in the false case.)
11:17justin_smith,(map > [1 2 3 4] [0 3 1 2] [-1 -1 -1 -1])
11:17clojurebot(true false true true)
11:17justin_smithit could be I misunderstood your question
11:17pflanze,(every true? (map > [1 2 3 4] [0 3 1 2] [-1 -1 -1 -1]))
11:17clojurebot#error {\n :cause "Unable to resolve symbol: every in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: every 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: every in this...
11:18justin_smith,(every? true (map > [1 2 3 4] [0 3 1 2] [-1 -1 -1 -1]))
11:18clojurebot#error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [clojure.core$every_QMARK_ invokeStatic "core.clj" 2553]}]\n :trace\n [[clojure.core$every_QMARK_ invokeStatic "core.clj" 2553]\n [clojure.core$every_QMARK_ invoke "core.clj" -1]\n [sandbox$eval72 invoke...
11:18justin_smithone more time...
11:18justin_smith,(every? true? (map > [1 2 3 4] [0 3 1 2] [-1 -1 -1 -1]))
11:18clojurebotfalse
11:18justin_smith,(every? true? (map > [1 2 3 4] [0 0 1 2] [-1 -1 -1 -1]))
11:18clojurebottrue
11:19jasonx2is there a function that does this? (1 2 3) and "foo" to ((1 'f') (1 'o') (1 'o') (2 'f') (2 'o') (2 'o') (3 'f') (3 'o') (3 'o'))
11:19pflanzejustin_smith, is this lazy? I guess no since those are vectors?
11:19justin_smith,(map list [1 2 3] "foo")
11:19clojurebot((1 \f) (2 \o) (3 \o))
11:19justin_smithpflanze: yes it is lazy, every? stops at the first false result
11:20pflanzeYes, but will map produce a 4-item list in any case?
11:20justin_smithpflanze: regardless of the input types, map and every? are lazy
11:20justin_smithso no, it is not eager
11:20pflanzeok
11:20pflanzeThanks!
11:20jasonx2just_smith in case it is isn't obvious, thats not the same :)
11:20scriptoryep, the call to every? will stop consume the result of map if it hits a false
11:20justin_smithjasonx2: iow "yes, except 'f' is not a clojure thing"
11:21jasonx2??
11:21clojurebot? is suddenly
11:21justin_smithjasonx2: oh, wait :)
11:21justin_smith,(for [x [1 2 3] y"foo"] (list x y))
11:21clojurebot((1 \f) (1 \o) (1 \o) (2 \f) (2 \o) ...)
11:21justin_smiththat's your answer (except it's \f not 'f' because 'f' is not clojure)
11:22jasonx2oh right. i actually know that
11:23justin_smith,'f' - exists, but is not what you might expect
11:23clojurebotf'
11:23justin_smithit's the symbol f'
11:26pflanze,(every? true? (map > [1 2 3 4] [0 0 1 2] [-1 -1 -1]))
11:26clojurebottrue
11:26pflanzeHm, actually it doesn't qualify for my given requirement.
11:26justin_smith,(symbol "'f'")
11:26clojurebot'f'
11:26pflanze(Unequal list lengths.)
11:26justin_smiththe lists are of equal length
11:26hyPiRionpflanze: what should it do if the lists are unequal?
11:27justin_smithoh no they are not
11:27pflanzehyPiRion, return false
11:27pflanzeOr give an exception which I could turn into a false.
11:28jasonx2,(every? true? (map > [1 2 3] [0 1 2 3 4 5]))
11:28clojurebottrue
11:28pflanzeI guess we're reaching the point where I'm going to write a function from scratch.
11:28justin_smith,(let [ls [[1 2 3 4] [0 0 1 2] [-1 -1 -1]]] (and (apply = (map count ls)) (every? true? (apply map > ls)))
11:28clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
11:28justin_smith,(let [ls [[1 2 3 4] [0 0 1 2] [-1 -1 -1]]] (and (apply = (map count ls)) (every? true? (apply map > ls))))
11:28clojurebotfalse
11:29justin_smithmuch uglier, but it works
11:29justin_smithonly use that if you won't get indefinite length input
11:29justin_smithotherwise you'll want something that doesn't use count
11:30pflanzeOf course, I can't compare infinite lists definitely.
11:30justin_smithor count them
11:30jasonx2,(length (range))
11:30clojurebot#error {\n :cause "Unable to resolve symbol: length in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: length 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: length in t...
11:30jasonx2,(count (range))
11:30pflanzeI was really expecting some (list-compare compare? l1 l2)
11:31clojurebotExecution Timed Out
11:31justin_smithpflanze: yeah, you can use compare, but that compares the lists, not the items
11:31justin_smith,(compare [1 2 3] [0 0 0 0])
11:31clojurebot-1
11:31justin_smith,(compare [1 2 3 4] [0 0 0])
11:31clojurebot1
11:32justin_smiths/lists/sequential things
11:32pflanze,(compare [1 2] [0 0])
11:32clojurebot1
11:32pflanze,(compare [1 2] [1 2])
11:32clojurebot0
11:32pflanzeYes, now a variant that takes a predicate.
11:32justin_smith,(doc compare)
11:32clojurebot"([x y]); Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than', 'equal to', or 'greater than' y. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable"
11:33jasonx2would you say clojure is closest to scheme, common lisp or haskell?
11:34justin_smithjasonx2: probably I'd put them in that order (most similar to scheme, etc.)
11:41jasonx2,(cycle '(1 2 3))
11:41clojurebot(1 2 3 1 2 ...)
11:41jasonx2function names, though, seem to match those in haskell often. i can just guess many, having dabbled in haskell before
11:41justin_smith,(shuffle (take 300 (cycle [1 2 3])))
11:41clojurebot[2 3 2 2 3 ...]
11:42scriptorthose function names tend to be common in functional programming in general
11:42scriptorrather than a haskell-specific thing :)
11:42justin_smithscriptor: well, haskell was invented as a coming together of all the functional langs
11:42jasonx2map is common. I can't say take or cycle are
11:43jasonx2ML?
11:43scriptorpossibly from ML
11:43justin_smithhaskell came from clean, miranda, ml, some others whose names I am forgetting
11:44hiredmanhttp://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH
11:44justin_smiththere were a bunch, a lot of them were closed source, it fragmented the pl research community in the '80s, so they got a conference together and invented haskell
11:45scriptorah, didn't know that
11:45scriptordid ocaml come about after haskell was conceived?
11:45justin_smithhmm - now I wonder
11:46scriptorcaml (without the o) is from '85
11:46justin_smithscriptor: https://en.wikipedia.org/wiki/Haskell_(programming_language)#History https://en.wikipedia.org/wiki/OCaml 1990 vs. 1996
11:48justin_smithvs. 1985 for the original caml, as you mention
11:49pepijndevosHalp. I refactored som Cljs code, and now it's way slower. At the top of Chome's profile is cljs$core$pr_writer_impl
11:49pepijndevosI'm not even printing anything.
11:50jasonx2how does ocaml compare to haskell, other than the obvious things (strict vs lazy evaluation)
11:51scriptorpepijndevos: does the profile show what is callingit?
11:52pepijndevosscriptor how do I tell? Further down there is cljs$core$print_map
11:52justin_smithjasonx2: in general haskell attempts to get speed via "cleverness" in the compiler and advanced static analysis, while OCaml attempts to get runtime performance via a simple and relatively uncomplicated compiler. The fascinating thing is they are not much different in performance.
11:54pepijndevoshmmm cljs.core.PersistentVector.toString
11:55justin_smithpepijndevos: could all this toString and pr_writer_impl stuff be invoked as a side effect ofthe profiling? it would be ironic...
11:55jasonx2justin what about language srmantics
11:56justin_smithjasonx2: like you mention, it's mainly about lazy vs. strict, though haskell tends to be more academic and experimental (this is their intended niche after all)
11:56pepijndevosahhhh, I mismatched some parameter which instead of throwing a type error got turned into a string somewhere.
11:56pepijndevosNot yet sure where, but setting the correct parameter order brings back the speed.
11:57justin_smithI guess that would do it...
11:57pepijndevosIt's way faster even.
12:25zxchey, can someone help me with lazy seqs? or should I go to #clojure-beginners?
12:25justin_smithzxc: you can go ahead and ask your question
12:25Olajydzxc, sorry i just joined, whats your question
12:25OlajydHi, justin_smith
12:26zxcI just need someone to explain them to me, I read chapter about them in brave clojure and I understand nothing
12:26zxcOlajyd: sorry for what? :)
12:26justin_smithzxc: that's kind of broad - do you have specific concrete questions maybe/
12:27zxcjustin_smith: I get that they don't process every value until I need it, but I don't understand this 32 value thing
12:28Olajydzxc: sorry I thought u asked a question on lazy seqs? I just went through the chat history and saw your question
12:28zxc(I'm coming from haskell world btw)
12:28zxcOlajyd: no, I've just joined
12:28Olajydok
12:28justin_smithzxc: I assume "32 value thing" is something that demonstrating chunking - that is, you can't assume that values not yet used are not produced
12:29justin_smithzxc: if you use lazily produced values in a "pure" way it's nothing to worry about
12:29zxc" In reality, Clojure "chunks" lazy sequences, realizing 32 members at a time"
12:29zxcthat's the sentence I have problems with
12:29justin_smithzxc: but a lazy function is allowed to produce values before you need them
12:29justin_smithzxc: it's an implementation detail
12:29justin_smithsome things chunk, some don't
12:29zxcso it produces 32 values and wait till I need 33th?
12:30justin_smith,(take 2 (map println (into [] (range 100))))
12:30clojurebot(0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\nnil nil)
12:30zxcor just not to worry about that and use it as I would use a lazy structure
12:30Olajydzxc : lazy-seq was introduced to make it possible to postpone any computation until data is needed
12:30justin_smithzxc: if you don't care about the side effects, it doesn't matter
12:31justin_smithzxc: but if you care about side effects, laziness is not the way to manage them
12:31justin_smithbecause chunking
12:31zxcit's my second day with clojure, I don't really now
12:31justin_smithsee the map println example above
12:31zxcI've only implemented fizzbuzz
12:31zxcjustin_smith: looked, thanks
12:32zxcand another question - I have this program in haskell and I want to rewrite it in clojure to see the difference
12:32zxcbut how to measure performance?
12:32zxcjvm is so slow to start
12:33zxchello world takes 1.2 sec, my haskell program did all computations in like 3 seconds, so it would be a big difference in time
12:33noncomfirst start the repl, them try (time (your-function))
12:33noncomdon't take the jvm startup time into account..
12:34zxcnoncom: so, in repl? thanks a lot!
12:34zxcnoncom: I just thought I need to fire up jar every time
12:34noncomno way!
12:34noncomlisps are all about repl
12:34noncomget yourself an IDE and work inside it
12:34noncomdon't work with the bare clojure jar
12:34zxcI'm working in spacemacs with cider
12:35noncomoh, that's fine
12:35zxcand repl in other window
12:35noncomalso, bear in mind that thanks to jvm jit, your 10th run of a function can take 10 times less! (a little over-generalized and exaggerated example, but just to make the point)
12:36zxcand final question - I don't have to know java to use their libraries, right? it's an awful language
12:36zxcnoncom: I'll write that down in my notebook!
12:36noncomwell.. java.. it depends on how much and what library you're using.
12:36noncomofcourse you do not have to program java in clojure
12:37noncombut some libraries may inforce this or that architecture and stuff
12:37noncombut in the end it all boils down to creating objects and calling methods on them...
12:37noncomoften there are clojure wrappers for many java libraries where it is worth and people took time to make them
12:38zxclet's say I want to create a simple game (not a gamedev type of programmer, just for example)
12:38noncomokay, so
12:38zxcdoes clojure provide all the important stuff?
12:38zxcgui and others?
12:38noncomumm, clojure is a language, you'll have to use a game engine of sorts.. which is a library
12:38noncomfor example, i am using JMonkeyEngine 3
12:38zxc"simple" - tic tac toe or something
12:39noncomah, i see
12:39noncomtake a look at seesaw
12:39akabanderThe seesaw samples include a Conway's Life example that includes a basic GUI
12:40noncomgoogle "seesaw gui"
12:40noncomseesaw is a swing wrapper
12:40zxcand I can use it without months of reading poorly written documentation?
12:41akabanderThat's a pretty subjective question
12:41akabanderWe don't know how fast you read
12:42zxcI learn and read pretty fast, I just have bad memories with gui (trying to use library with no documentation and one crappy tutorial)
12:42noncomzxc: yes
12:42zxcnoncom: darn, clojure rocks
12:42noncomno, just try seesaw
12:42zxcthank you all :)
12:42hanate_monstahello, beautiful clojuristas, question : which is the equivalent to a sparse array in clojure?
12:42noncomif anything, ask here. many ppl had some experience with it
12:42akabanderIf you know anything about Swing, seesaw will be easy
12:42akabanderYou could use a map for a sparse array
12:42zxcakabander: you mean dancing?
12:43noncomand swing is not much different from any other modern gui system in its terms
12:43noncomswing is one of java gui systems
12:43hanate_monstaakabander: example of thee?
12:43zxcoh, I don't know java, it scared me to the bone
12:44hanate_monstazxc: Is so easy to learn, nothing to be scare
12:44noncomdon't be afraid. just know one thing: java for jvm is like c for metal
12:44noncomin clojure you won't have to work with much java anyway (in most cases)
12:44hanate_monstazxc: the thing is is verbose and mudane as oppose to clojure
12:44akabanderI would use a map and just use the index values for keys.
12:45hanate_monstaakabander: Thank you
12:45zxchanate_monsta: I know it's easy, I just want to cry seeing all these classes and privates and inheritances
12:45akabander(def sparse-array {})
12:45akabander(merge sparse-array { 0 12, 1 13 }
12:45akabander)
12:46akabanderThen you can just do (sparse-array idx) to get the value at idx.
12:46noncomzxc: then you're in the same boat as rich hickey - the creator of clojure. he does not like oop either :)
12:46zxcnoncom: I also look like him, which is funny
12:46akabanderOOP is a straightjacket -- useful when you have to work with insane people.
12:47hanate_monstanoncom: is not that he doesn't like, he is just tired of using it
12:47noncomwow :)
12:47zxcI think we all have functional souls
12:47noncomyeah )
12:48zxcand final final question - are there any better error messages? or do I have to get used to them?
12:48zxcI get 20 lines or so when I forget to close parens
12:48hanate_monstazxc: But some people like to objectify bodies (specially womans bodies) (o-^)
12:49fantazobtw. what is the current hotness in clojure webdev?
12:49fantazostill noir and compojure?
12:49hanate_monstaI actually like to use immutant
12:49hanate_monstawith compojure and ring
12:49hlshipzxc: io.aviso/pretty exists to clean up the stack traces; part of what it does is hide frames that aren't going to be helpful, such as anything in the clojure.lang package.
12:50zxchanate_monsta: but treating women like objects isn't nice
12:50hanate_monstazxc: I know, never done that.
12:50hanate_monstajust saying
12:51zxchlship: and just add this as a package?
12:52zxchanate_monsta: my c++ friend does this all the time, which is also funny
12:52zxchanate_monsta: but enough non-clojure stuff for now!
12:53hlshipzxc: see the docs; there's an explicit function to call that goes all alter-var-root! on some key clojure.main and clojure.repl functions to hook in better exception reporting.
12:53hlshiphttps://portal.aviso.io/#/document/open-source/pretty/Current
12:53zxchlship: thank you, have a great day :)
13:22AcugHello
13:24justin_smithzxc: yeah, the error messages really don't get a lot better (though aviso and such can help) - clojure doesn't abstract over the jvm's call stack, which is great for performance but bad for things making any sense when an error happens
13:32zxcjustin_smith: is it possible to actually read something from this madness after few months or so?
13:33justin_smithzxc: sure - it's a call stack, which means that if you go far enough up you'll find either a) your code which invoked this crazy deep stack of calls or b) a mechanism like core.async or some other threaded or async pipeline that runs code for you
13:34zxcjustin_smith: thank you!
13:34justin_smithzxc: complecting factors here is that clojure has little to no defensive code, so call stacks go pretty deep before errors are found usually
13:34zxcjustin_smith: defensive code?
13:35justin_smithzxc: input validation
13:35justin_smithpre-conditions
13:35justin_smithtype checks
13:35justin_smithetc.
13:36zxcjustin_smith: oh, okay. but being dynamic isn't a huge pain, right?
13:38fantazowe all just want to have very strict type checks, right? no?
13:39akabander<-- does not want unrequested type checks
13:39zxcin haskell everything was pure and strict and strongly typed, so I don't know how it is working with dynamic lang
13:41akabanderBeing passed a "wrong" type is typically the result of a logic error... If it's easy to reason about your logic, type errors become harder to commit.
13:42akabanderBut I'm naive, and use maps a lot. If something doesn't have the key I need, I just stop processing it.
13:43justin_smithakabander: zxc: yeah, regardless of our value judgments etc. I think the factual statement "there is little to no defensive coding in clojure" is something we can agree on (except for explicit exceptions like core.typed or prismatic/schema of course)
13:44justin_smithzxc: original point being that lack of defensive coding means an error gets pretty far down the call stack into internals before being reported. A natural correlary to this of course is that if you code defensively, you can cause the resulting call stack to be shorter and hey you even have the option of providing a sensible message.
13:45akabanderI feel like I trip over strict type enforcement more often than I screw up due to dynamic persmissiveness. This may be a problem that will go away as I get better with Clojure...
13:45zxcjustin_smith: okay, thanks for explaining
13:46rhg135Too bad preconditions don't let you specify the exception
13:46akabanderYeah the explanation is enlightening
13:47justin_smithrhg135: asserts do though (assert (OK) "well this time it was not OK")
13:47akabanderIt's not an exception, it's a ValueError, right?
13:47justin_smithassertionerror
13:47akabander<-- missed it by " much
13:47rhg135Yup
13:48justin_smithrhg135: something I am fond of nowadays (assert (OK input) (str "input was not OK:" (pr-str input)))
13:48rhg135Pres are nice in theory
13:48justin_smiththe pr-str is useful for disambiguating some types of input data in a way that str alone won't
13:49rhg135I see
13:49pepijndevosErm, my Clojurescript code doesn't work with advanced optimisations turned on. Do I need to tell it to not remove certain parts?
13:50justin_smith,(print {:a 0 "b" 1 'c 2 'd "3 :a 0"})
13:50clojurebot{:a 0, b 1, c 2, d 3 :a 0}
13:50rhg135~Externs
13:50clojurebotPardon?
13:50rhg135Meh
13:50justin_smith^ that print is extremely misleading
13:51justin_smith,(print {:a 0 "b" 1 'c 2 'd "3, :a 0, :even worse"})
13:51clojurebot{:a 0, b 1, c 2, d 3, :a 0, :even worse}
13:51akabanderjustin_smith: Add a comma in that quoted string and you'll have a winner
13:51justin_smithright
13:51justin_smith,(prn {:a 0 "b" 1 'c 2 'd "3, :a 0, :even worse"})
13:51clojurebot{:a 0, "b" 1, c 2, d "3, :a 0, :even worse"}\n
13:51justin_smithpr-str does the same magic as pr / prn
13:57rhg135That's great for confusing people
13:59justin_smithrhg135: yeah, that's why I use pr-str whenever I print any data
15:14sdegutisHow long has {:arglists ...} been accepted before any function definitions in `defn`?
15:14sdegutisI've never seen this until now. What's the purpose of it? Just for documentation only?
15:14justin_smithsdegutis: to get away with filthy lies
15:15sdegutisYes understood, but I meant technically.
15:16sdegutisAnyway, I upgraded from Ring 1.2.1 to Ring 1.4.0 and everything's broken.
15:16justin_smithit's for things like macros - to give some of them doc strings that make sense
15:16sdegutiswrap-reload seems to completely not work at all anymore, my own wrap-error is ignored in favor of Jetty showing its very own exception handler somehow, etc
15:17justin_smithsdegutis: the actual number of args a macro gets when invoked internally is greater than the documented arg list, and some macros are "bootstrapped" from normal function definition
15:17sdegutisjustin_smith: this is in a defn as mentioned, not defmacro
15:18justin_smithsdegutis: I'm not telling you why ring is lying, I am describing why it has to be possible for clojure to make sense
15:18sdegutisok
15:18justin_smithiirc Bronsa and arrdem had some choice words on the habit of arglist hacking
15:19Bronsahate whoever does that with a passion.
15:19sdegutis:)
15:19sdegutisTIL Bronsa hates weavejester with a passion https://github.com/ring-clojure/ring/commit/3c55e006f816d0e971bf671eede9729137a46329
15:20sdegutisbut only started hating him on May 18 last year so that's not as bad
15:21sdegutisWhoa:
15:21sdegutis,(:foo {} :missing)
15:21clojurebot:missing
15:21sdegutisdid not know
15:21sdegutis,({} :foo :missing)
15:21clojurebot:missing
15:21sdegutishaha
15:21sdegutisstupid clojure always being way more pragmatic than is necessary
15:27sdegutis_back
15:30{blake}arglist hacking?
15:30sdegutis_Is there a way within an uberjar to find all namespaces matching a given prefix before any of them are loaded?
15:31sdegutis_And then load them?
15:39{blake}I can't even. Though we do some dynamic namespace loading, it's all external to the JAR being run.
15:40sdegutis_oh?
15:40sdegutis_how's that?
15:46sdegutis_AHA just figured out the reloading issue
15:48sdegutis_See, when you have namespace A with (def a [B/foo]) and namespace B with (def b [C/bar]) then it doesn't matter if you (require 'C :reload), because A/a will still be [[C/bar]] with the old version of C/bar, not the new reloaded one.
15:48sdegutis_So it turns out my bug is a Clojure namespace issue, right?
15:53sdegutis_Clojure is not dynamic and should stop pretending to.
15:59hiredmanwhen you don't know where you are, what is around the bend is always a surprise
16:00sdegutis_hi hiredman
16:03sdegutis_i didnt know u were buddhist
16:08{blake}sdegutis_: So...reload A & B, too, right?
16:10{blake}It seems like you're asking for EXTREME mutability. In which case, I recommend Smalltalk.
16:12sdegutis_{blake}: I found this bug using Ring's wrap-reload middleware which is pretty popular so it's not some obscure wishlist.
16:12sdegutis_Clojure's (require foo :reload) is inherently unreliable as of Clojure 1.7
16:12sdegutis_It will reload the namespace, but if anyone already held some of its vars, what they now hold is up for grabs.
16:13sdegutis_If only Clojure's issue tracker was hosted on Github, I could report this to them and they might be able to fix it. Oh well.
16:14bendlassdegutis_: ring's bug tracker is on github, they will pass it on, if it's actually a language bug
16:15srrubyI'm puzzled by *1 (yes that is the digit 1). It evaluates to nil in the repl. Anyone know why?
16:15sdegutis_bendlas: I've put it there. I doubt they'll pass it on but hope you're right.
16:15sdegutis_srruby: it's a fake var that always evaluates to the result of the last entered expression
16:15srrubythks
16:15Bronsa,#'*1
16:15clojurebot#'clojure.core/*1
16:16Bronsasrruby: *1 is a clojure.core var that holds the last expression evalauted at the repl
16:16Bronsathere's also *2 and *3
16:16sdegutis_srruby: *2 is second-to-last etc
16:16sdegutis_{blake}: I'm not asking for extreme mutability. Just wishing (require ... :reload) didn't have so many caveats/bugs as to make it unusable.
16:16Bronsaand *e holding the last exception
16:16hiredmanhttp://clojure.org/repl_and_main#toc3
16:16sdegutis_Oh wow I didn't realize *1 was in clojure.core
16:16sdegutis_sick
16:17bendlassdegutis_: can you post a test case? vars are supposed to be reload-stable.
16:17sdegutis_I can try to make one.
16:18bendlassdegutis_: please do, if your observation is correct, that would be a serious bug
16:19sdegutis_will do
16:19{blake}Is (require ... :reload) how "lein ring server" reloads detected changes?
16:19bendlassdegutis_: I suspect that the stale thing you end up holding onto isn't actually the var anymore, but an old value that it used to hold
16:20bendlasi.e. the result of dereferencing it
16:20bendlase.g. when you start a ring server you usually pass the #'handler var, to make it reloadable
16:21sdegutis_bendlas: ah probably yes
16:21sdegutis_In my real life usecase, it was a nested set of defroutes
16:21sdegutis_Which creates a var to a function, which I then nest by resolving the var in the typical way (foo)
16:23bendlassdegutis_: look out for cases of (let [foo the-var] (fn [_] (foo))), here the fn calls the already dereferenced value
16:24sdegutis_Right.
16:33sdegutis_So in this case, it's not really a bug.
16:33sdegutis_I just need to always write #'foo instead of foo if I ever want dynamic code reloading to work.
16:33sdegutis_Right?
16:36sdegutis_Makes sense.
16:38bendlassdegutis_: only for higher-order functions, i.e. when you get a function value
16:38bendlasfor normal var usage like (foo), the var is dereferenced every time, implicitly
16:38sdegutis_Why not also for data like vectors?
16:38sdegutis_Um..
16:38sdegutis_So only in defroutes then?
16:39sdegutis_Compojure is so stupid, I should just make the jump to Silk or Bidi now and get it over with.
16:39bendlasnot even there for most cases
16:39bendlashm, cgrand's moustache is also pretty cool
16:40sdegutis_I don't remember much about it except that when I compared it with the others a year ago it seemed like a terrible option.
16:42bendlassdegutis_: I like it, because it facilitates writing small, focussed handler fns + it has a syntax slot for middleware
16:43sdegutis_I prefer lists of routes like [request-type route-string handler-fn] and to just use string comparison to find a match.
16:44sdegutis_This option much more sense to me.
16:44spieden-+1 bidi last i looked
16:51sdegutis_lazybot: wake up
16:51sdegutis_no, dont do this.. wake up.. you're just sleeping lazybot
16:51sdegutis_you're just sleeping. its gonna be alright. everythings gonna be alright, just open your eyes, wake up
16:52sdegutis_please, please just wake up lazybot? please?
16:54DomKMsdegutis_: Both Silk and Bidi are great options. I'm happy to help with any questions you might have about Silk.
16:54sdegutis_DomKM: which one did you make? i forget
16:54sdegutis_oh sorry
16:54DomKMSilk
16:54sdegutis_silk. right.
16:57sdegutis_DomKM: I gave my feedback a while ago https://github.com/DomKM/silk/issues/14
16:57sdegutis_DomKM: In the end I ended up with Bidi because I couldn't really figure out how to use Silk from the readme
16:57sdegutis_But basically they seemed like nearly identical projects.
17:01DomKMsdegutis_: I agree with your complaint about the readme. The issue is still open and unresolved. I just haven't had time to do it and haven't prioritized it because I am rewriting most of Silk. If you're interested, you can follow along in the `fsm` branch.
17:01sdegutis_DomKM: not really but thanks for the offer
17:01sdegutis_im not opposed, just no compelling reason anymore since bidi works fine
17:03DomKMsdegutis_: In terms of differentiation, Silk used to be the only routing library that was compatible with both Clojure and ClojureScript. Now that Bidi supports ClojureScript, you're right that they are very similar. I think the next version of Silk will provide a very compelling reason to choose it but for now I think that your assessment is correct.
17:03sdegutis_DomKM: dont just tease, what will be compelling about it?
17:04DomKMheh
17:06spiedenfsm.. it's a finite state machine!?
17:07DomKMsdegutis_: Yeah. I ported Automat (https://github.com/ztellman/automat) to ClojureScript. I'm using it, instead of regexes, for matching. It is far more composable and way faster.
17:07spiedensweet
17:08DomKMsdegutis_: Got a meeting now. Be back soon.
17:08sdegutis_oh man
17:08sdegutis_all these puns
17:08sdegutis_its 2 much 4 me
17:08sdegutis_Automat
17:08clojurebotCool story bro.
17:08spiedenexcept for some little ones sprinked into productions for the character classes
17:08sdegutis_he should have named it "Pun A".
17:08sdegutis_the next guy to name a library something with a pun should name it "Pun B"
17:08sdegutis_thatll save us all some time
17:09sdegutis_or Untitled
17:09sdegutis_and Untitled 1
17:09sdegutis_etc
17:11justin_smithsdegutis_: I think we should outsource this request, I know a good contracting company in Punjab
17:11sdegutis_oh man
17:11sdegutis_my side
17:11sdegutis_it hurts
17:11sdegutis_from the cancer
17:11sdegutis_not from laughing dont get me wrong
17:11sdegutis_jk i dont have cancer yet
17:13justin_smithRIP in peace sed utils
17:15t0byIANAD but you may have cancer of the sense of humor.
17:15t0byIt's a serious condition.
17:16bendlascool puns, you've got there, people. would be bad if something came to parse with them.
17:28sdegutis_justin_smith: finally someone says my name right
17:28sdegutis_the g is for gnu
17:28sdegutis_and the gnu is for ngnu which is short for "not gnu because gnu sucks" - its a backronym
17:28sdegutis_srlsy tho stallman should be fired
17:31justin_smithsdegutis_: Mallory Ortberg suggests that the best way to deal with trolls is to address them as Steven.
17:31justin_smithsdegutis_: she reports that calling them Stephen also works.
17:31sdegutis_nobody knows who this lady you made up is go home troll 2/10
17:32sdegutis_am i doing a good Bronsa impersonation?
17:33justin_smithsdegutis_: https://twitter.com/mallelis/status/634077312854720513
17:34sdegutis_wow she knows her stuff
17:34sdegutis_whoa
17:34sdegutis_You are blocked from following @mallelis and viewing @mallelis's Tweets. Learn more
17:35sdegutis_so im guessing this mallory lady doesnt support peoples rights to sexually identify as attack helicopters?
17:35sdegutis_cant see any other reason id be "blocked"
17:53sdegutis_lazybot: wake up this isnt funny
17:53sdegutis_lazybot: dont, just dont, stop pretending, you're just sleeping i know it I KNOW IT
18:05Or1Equals1--How is everyone doing today?
18:10spiedengood you?
18:13rhg135lazybot is dead mate, just let him go
18:20sdegutis_NOOOOOOOOOOOOOO.com
18:20spiedenit can't be. must be live lock
18:21sdegutis_ugh https://github.com/weavejester/clj-aws-s3/issues/83
18:21sdegutis_ugh ugh ugh
18:30gfrederi`sdegutis_: have you done `lein clean`?
18:30sdegutis_yes
18:31gfrederi`I would add more information to the ticket if you want to get help with it
18:32sdegutis_I added lots more.
18:32sdegutis_Just now.
18:43rhg135huh the title is quite long
18:47sdegutis_yeah its got all those more information
18:48sdegutis_Shortened it.
18:55sdegutis_whoa
18:55sdegutis_what the heck, you cant even do (import com.amazonaws.ClientConfiguration) now?
18:55sdegutis_this just started happening.
18:55sdegutis_todya.
18:56{blake}Is it possible to force a lazy-seq to realize item by item (rather than in chunks of 32)?
18:56sdegutis_why?
18:56clojurebotwhy not?
18:56sdegutis_,(import com.amazonaws.ClientConfiguration)
18:56clojurebot#error {\n :cause "com.amazonaws.ClientConfiguration"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "com.amazonaws.ClientConfiguration"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged ...
18:57justin_smith{blake}: if you google for "unchunk" you'll find the magic. Then you should ask yourself why you are relying on lazy results for side effects and probably stop doing that.
18:57{blake}Reazlizing the chunk creates an error--I'm reading a database--and I can't figure out which database record is actually causing the problem.
18:57justin_smithyeah, there are various versions of unchunk out there, all the ones I have tried work
18:57justin_smithmaybe someone has one in a util lib
18:58{blake}justin_smith: It's Monger. I'm not...doing any of that stuff you say. =P
19:00justin_smith{blake}: sorry, I was being a bit glib. Unchunk will prevent the chunking related problems. So would passing (take N input) to monger instead of your input
19:00justin_smithunless this problem is internal to monger -in which case, fork mongo?
19:00justin_smith*monger that is
19:01{blake}justin_smith: It's internal to mongo, comes from the Java driver, and I'm not sure if you mean "fork" euphemistically or literally.
19:01justin_smithwell, change its internals, right?
19:01justin_smithbecause you can't make its input not chunk from the outside...
19:02{blake}justin_smith: Grrr. Yeah.
19:08{blake}Am I misunderstanding something? If I'm realizing a sequence of records and one record in a chunk causes an exception, and this isn't in my code, I really can't handle that exception at all, right? I mean, not in the sense of skipping that problematic record and moving on.
19:09justin_smithnot really, I don't think so
19:10{blake}So that's a legitimate issue with monger. And something to be avoided if you're writing your own library.
19:10justin_smithI guess so - is this like a corrupt record or something?
19:13{blake}justin_smith: I =think= so. I don't know what else it could be. And I'm not the only one to run into it. But I can't locate it. I've heard one suggestion it was just missing data, but that shouldn't be an issue.
19:21WickedShellI'm slowly leaking memory that leads to an eventual crash, and every GC the metaspace grows in size (JDK 1.8.0_20) I'm having trouble tracking down what is causing the leak. Does anyone have a good tutorial for finding these/looking through a heap dump? I can't figure out how to trace the char[] byte[]'s etc to where they are created
19:22BronsaWickedShell: what clojure version are you using out of curiosity?
19:22WickedShell1.7
19:22{blake}OK, I think I just need to use find instead of find-map. Which I guess is a "duh".
19:22WickedShellNo, wait 1.6.... Not sure why actually
19:23BronsaWickedShell: ok, just asking because there are suspicions of a memory leak introduced with one of the new 1.8 alphas
19:32WickedShellI think I could trace it through the current heap dumps I'm getting if I could figure out how to trace allocations back to my code/see what causes objects to be allocated, but I can't figure out how to do that
19:37amalloyi don't think heap dumps have that information unless you have a profiler attached and enable allocation profiling
19:54sdegutis_,(import '[com.amazonaws ClientConfiguration])
19:54sdegutis_what am i doing wrong
19:54clojurebot#error {\n :cause "com.amazonaws.ClientConfiguration"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "com.amazonaws.ClientConfiguration"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged ...
19:57justin_smithsdegutis_: well for starters that jar isn't on the classpath for clojurebot
19:58justin_smithsdegutis_: mv ~/.m2 ~/.old-m2 effectively does the same thing, but it easier to undo if it didn't help
19:58justin_smithunless your network is super fast, or you like watching jars download
19:58sdegutis_75mbps or something
19:58sdegutis_so meh
19:59sdegutis_still downloading....
19:59justin_smithit's the magic behind tab-completion in the repl
19:59justin_smithusually some plugin for nrepl pulls it in
19:59sdegutis_oh
19:59sdegutis_reply
19:59sdegutis_thanks trptcolin
20:00sdegutis_wherever u be
20:00sdegutis_yep i can officially no longer use clj-aws-s3
20:00sdegutis_:'(
20:00sdegutis_something is major broken
20:00sdegutis_cant figure out where or what
20:01justin_smithany snapshots?
20:01justin_smithany major plugin version changes?
20:01justin_smithor just plain dep changes? because without those things shouldn't be different
20:03sdegutis_shoooooot
20:04sdegutis_it was the datomic upgrade.
20:04sdegutis_just confirmed.
20:04sdegutis_using the latest datomic peer client clojure lib breaks amazon's s3 jar completely
20:05sdegutis_i had no suspicion datomic was using s3, should have known
20:05justin_smithoh, incompatible versions?
20:08sdegutis_no clue
20:08sdegutis_ill try excluding their version or something
20:37sdegutis_phew fixed. just had to downgrade to weavejester's older version of clj-aws-s3