#clojure log - Aug 05 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:01 lsdfajklsd: test

0:01 rhaywood: yt?

0:01 justin_smith: ran 0 tests with 0 assertions, 0 fails, 0 errors

0:02 lsdfajklsd: rhaywood: (+ 1 1)

2:54 tdammers: hi... is this the right place for questions about clojurescript and figwheel?

2:56 Empperi: ok place, but #clojurescript is better

2:57 tdammers: aight

8:35 tgoossens: How do I typehint a 2d array?

8:37 justin_smith: , (into-array [(into-array [5])])

8:37 clojurebot: #object["[[Ljava.lang.Long;" 0x5d642c1f "[[Ljava.lang.Long;@5d642c1f"]

8:37 justin_smith: "[[Ljava.lang.Long;", though the java.lang.Long part is variable of course

8:38 "[[Lfoo'\;"

8:38 you can use the string where normally you would provide a class or keyword

8:42 tgoossens: justin_smith, again my hero of the day thanks!

8:53 snowell: (inc justin_smith)

8:53 lazybot: ⇒ 284

8:54 hellofunk: what is easiest way to build binary number of arbitrary length with all bits turned on?

8:54 i.e. if i need length it builds 2r11111

8:54 length 5

8:56 chouser: ,(Long/toBinaryString (- (bit-shift-left 1 5) 1))

8:57 clojurebot: "11111"

9:00 justin_smith: ,(read-string (apply str "2r" (repeat 5 1))) ; less elegant

9:00 clojurebot: 31

9:00 justin_smith: err

9:01 hellofunk: justin_smith: that is the correct result

9:01 just not printing as binary

9:01 which is fine

9:01 justin_smith: hellofunk: ahh, right

9:01 the bit-shift is probably two orders of magnitude faster :)

9:01 hellofunk: i suspect there is still a clever elegant option to using xor

9:02 I was thinking that 2r100000... xor with 0 will always be 2r011111....

9:02 wait

9:02 i mean bit-not, not xor

9:03 i should not think out loud

9:04 blackbird_: I have a line like (def tmc (client/text-connection (env :cache-endpoint))) When doing like `lein ring uberwar`, this fails because the env variable doesn't exist there and it attempts to create a connection to nil. Is there a general patterin for dealing with this type of thing?

9:05 hellofunk: i think i'll go with the chouser offering

9:05 chouser: Don't be too hasty. There may be benefits to the string-manipulation version that we haven't thought of yet. ;-)

9:06 justin_smith: blackbird_: the easy way is (def tmc (delay (clien/text-connection ...))) and then use @tmc where you would use tmc

9:06 blackbird_: the super proper way is to use stuartsierra/component for resources that are stateful

9:06 chouser: ,(nth (iterate #(+ 1 (* 10 %)) 1) 5)

9:06 clojurebot: 111111

9:07 chouser: oh, whoops, that's base 10

9:07 (Long/toBinaryString (nth (iterate #(+ 1 (* 2 %)) 1) 5))

9:07 ,(Long/toBinaryString (nth (iterate #(+ 1 (* 2 %)) 1) 5))

9:07 clojurebot: "111111"

9:08 blackbird_: justin_smith: ahh cool. component way seems like overkill for one def, thanks for the tip

9:09 chouser: ,(Long/toBinaryString (eval (read-string (nth (iterate #(str "(+ 1 (* 2 " % "))") 1) 5))))

9:09 clojurebot: "111111"

9:09 opqdonut: ,(Long/toBinaryString (dec (bit-shift-left 1 6)))

9:09 clojurebot: "111111"

9:10 opqdonut: oh that was mentioned already ages ago

9:10 justin_smith: the bit-shift/dec combo is the best though

9:10 chouser: opqdonut: dec, of course!

9:10 nicely done

9:10 opqdonut: well it's actually the same number of characters as - 1 :)

9:11 chouser: hm, true. I prefer dec.

9:15 opqdonut: me too

9:16 I even use it on floats, but feel a bit dirty afterwards

9:17 justin_smith: ,(dec (/ 131 7))

9:17 clojurebot: 124/7

9:20 justin_smith: ,(inc (/ 17 7)) ; how I rock it

9:20 clojurebot: 24/7

9:34 tgoossens: How (using leiningen) can I compile java and clojure code AND have a java class use a class generated by clojure gen-class.

9:34 This is a problem since java is compiled first and then clojure

9:34 but in this particular case, clojure should be compiled before this one class

9:34 can I express such things in leiningen?

9:35 gfredericks: tgoossens: do you know for sure that you have to structure it that way? there are other ways of calling clojure code from java code

9:35 that don't require that order of compilation

9:35 hyPiRion: tgoossens: https://github.com/hyPiRion/multicompile-example

9:36 essentially just do prep-task modifications

9:39 chouser: or move the gen-class code to another "project" and bring it in as a lein dep

9:42 TimMc: or use make

9:47 tgoossens: I added it as a Junit test (which in the end made more sense)

9:54 TimMc: fascinating

9:54 Was it in fact a test?

10:01 wes_: hello. I've got a question if you've got time.

10:02 justin_smith: wes_: on IRC you don't need to ask, you can just ask

10:02 namra: wes_: just ask ^^

10:02 ^^

10:04 wes__: I want to apply a function to a seq with an init value and use the result of the function as the init value for the following iterations.

10:04 justin_smith: wes_: that's reduce

10:05 ,(reduce + 2 [3 4 5])

10:05 clojurebot: 14

10:05 gfredericks: ,(reduce str 2 [3 4 5])

10:05 clojurebot: "2345"

10:05 gfredericks: ,(reduce - 2 [3 4 5])

10:05 clojurebot: -10

10:05 gfredericks: ,(reduce / 2 [3 4 5])

10:05 clojurebot: 1/30

10:05 justin_smith: ,(reduce conj [] [7 8 9])

10:05 clojurebot: [7 8 9]

10:05 gfredericks: ,(reduce vector 2 [3 4 5])

10:05 clojurebot: [[[2 3] 4] 5]

10:06 justin_smith: ,(reduce conj () [7 8 9])

10:06 clojurebot: (9 8 7)

10:06 gfredericks: ,(reduce hash-set 2 [3 4 5])

10:06 clojurebot: #{#{4 #{3 2}} 5}

10:06 justin_smith: yeah, reduce is the greatest

10:06 gfredericks: (reduce reduce ? [? ? ?]) ;; ← make this work

10:06 wes__: (defn move-up [map vec-of-maps index] ...) -> new vec-of-maps with item moved to index

10:07 (reduce move-up vec-of-maps seq-of-maps) <---- this turns some of my maps into vectors of [k v]

10:07 gfredericks: ,(reduce reduce conj [[1 2 3] [4 5 6] [7 8 9]])

10:07 clojurebot: #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IPersistentCollection"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IPersistentCollection"\n :at [clojure.core$conj__4104 invokeStatic "core.clj" 82]}]\n :trace\n [[clojure.core$conj__4104 invokeStatic "core.clj" 82]\n [clojure.core$conj__4104 invoke "core.clj" -1]\n [c...

10:07 gfredericks: dangit

10:08 ,(reduce reduce + [[1 2 3] [4 5 6] [7 8 9]])

10:08 clojurebot: #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [clojure.core$reduce invokeStatic "core.clj" 6516]}]\n :trace\n [[clojure.core$reduce invokeStatic "core.clj" 6516]\n [clojure.core$reduce invoke "core.clj" -1]\n [clojure.lang.PersistentVector reduce "Persist...

10:08 justin_smith: wes__: it would do that if seq-of-maps was actually a map

10:08 gfredericks: welp I give up

10:08 justin_smith: wes__: also, how are you giving a three-arg function to reduce?

10:09 wes__: woops. move-up takes two args [item coll] and uses (.indexOf coll item) to call insert-at....

10:11 justin_smith: so you have a vector of maps, and a seq of maps, and your reduce is to take each item in the seq of maps and find its position in the vector and then...

10:12 tgoossens: in leiningen with ':aot' how do I set two values?

10:13 justin_smith: tgoossens: so you have two totally unrelated namespaces that should be aot compiled? aot is transitive, so aot compiling an ns also aot compiles all its deps

10:13 wes__: move-up takes a single map and a vector of maps, finds the index of the item in the vector and produces a new vector of maps in which the item resides at (dec index)

10:13 hyPiRion: tgoossens: what do you mean by two values? :aot [myns.first myns.second] will compile both namespaces, regardless of their dependency to one or another

10:13 tgoossens: hyPiRion,

10:14 justin_smith: wes__: OK, that should totally work

10:14 tgoossens: hyPiRion, That is what i mean

10:14 hyPiRion: ah, nice

10:14 tgoossens: thanks :)

10:14 wes__: so, (reduce move-up seq-of-items vec-of-maps) ??

10:14 lazybot: wes__: Uh, no. Why would you even ask?

10:15 justin_smith: wes__: the vec should come before the seq

10:15 since you can't update a seq by index

10:16 wes__: ok, i'll give it a go.

10:16 justin_smith: and more generally, reduce takes its accumulator before the sequence it walks

10:20 Olajyd_: Please how can I compare date-values in clojure to determine which is greater?

10:20 justin_smith: Olajyd_: compare

10:20 ,(java.util.Date. 0)

10:20 clojurebot: #inst "1970-01-01T00:00:00.000-00:00"

10:20 justin_smith: ,(java.util.Date.)

10:20 clojurebot: #inst "2015-08-05T14:21:01.504-00:00"

10:21 justin_smith: ,(compare (java.util.Date.) (java.util.Date. 0))

10:21 clojurebot: 1

10:21 pbx: nice demo justin_smith

10:21 justin_smith: heh, thanks

10:23 gfredericks: $google gfredericks compare

10:23 lazybot: [gfredericks (Gary Fredericks) · GitHub] https://github.com/gfredericks

10:23 gfredericks: well https://github.com/gfredericks/compare

10:24 if you don't like writing your own -1/0/1 logic

10:24 justin_smith: gfredericks: handy!

10:24 oddcully: and if you don't need it for sorting, there is also .before/.after

10:24 gfredericks: justin_smith: !!!

10:25 wes__: So, I tried this and it gives a vector of vector of vector of maps

10:26 sdegutis: Given (defn foo [x y z] ...) and (defn bar [x y] (foo x y z)), how can I redefine bar so to remove the parameter redundancy?

10:27 Hi.

10:29 I thought it would have something to do with partial, but nope.

10:29 wes__: (move-up 'b ['a 'b 'c]) => [b a c]

10:29 justin_smith: wes__: (defn move-up [v i] (let [pos (.indexOf v i)] (if (pos? pos) (-> v (assoc pos (v (dec pos))) (assoc (dec pos) i)) v)))

10:29 wes__: needed the if for cases where i is not in the vec, or i is already at position 0

10:30 sdegutis: Clearer definitions are probably (defn foo [x y z] ...) and (defn bar [x y] (foo x y "some z")),

10:30 justin_smith: ,(defn move-up [v i] (let [pos (.indexOf v i)] (if (pos? pos) (-> v (assoc pos (v (dec pos))) (assoc (dec pos) i)) v)))

10:30 clojurebot: #'sandbox/move-up

10:30 justin_smith: ,(move-up 'b '[a b c])

10:30 clojurebot: #error {\n :cause "No matching method found: indexOf for class clojure.lang.Symbol"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching method found: indexOf for class clojure.lang.Symbol"\n :at [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]}]\n :trace\n [[clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]\n [clojure.lang.Reflector invo...

10:30 justin_smith: ,(move-up '[a b c] 'b)

10:30 clojurebot: [b a c]

10:30 justin_smith: oops I flibbed your args

10:30 but it works otherwise :)

10:30 perplexa: :D

10:32 justin_smith: shorter: (defn move-up [v i] (let [pos (.indexOf v i)] (if (pos? pos) (assoc v pos (v (dec pos)) (dec pos) i) v)))

10:33 wes__: I recommend that arg order, because the idiom in clojure is that the associative item comes first

10:33 wes__: and even more important, the rules of reduce says the accumulator (the vector) must be the first arg

10:34 perplexa: ,(move-up '[a b c] 'c)

10:34 clojurebot: #error {\n :cause "Unable to resolve symbol: move-up in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: move-up 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: move-up i...

10:34 justin_smith: ,(defn move-up [v i] (let [pos (.indexOf v i)] (if (pos? pos) (assoc v pos (v (dec pos)) (dec pos) i) v)))

10:34 clojurebot: #'sandbox/move-up

10:34 perplexa: ,(move-up '[a b c] 'c)

10:34 clojurebot: [a c b]

10:34 justin_smith: now try - clojurebot is forgetful :)

10:34 perplexa: hehe

10:34 alzheimerbot ;p

10:35 wes__: oh, so to write a function that is reducable, I've got to have the accumulator as the first argument?

10:35 justin_smith: yes, always

10:35 Olajyd: @justin_smith: How can i comapre date values in clojure?

10:35 wes__: Thanks. That's a great help.

10:35 sdegutis: Wait!

10:35 Is this even possible!?

10:35 justin_smith: Olajyd: didn't I just show that above?

10:36 Olajyd: the compare function will return -1, 0, or 1 depending on how two dates compare

10:36 sdegutis: I actually have this: (defn change [db entity attr value] ...) and (defn change-text [db entity value] (change db entity :text value))

10:36 Can I simplify the definition of change-text at all?

10:37 I tried using partial but I must be doing it wrong because that helps naught.

10:37 *not

10:37 justin_smith: sdegutis: maybe flatland/useful has some kind of flipped partial

10:37 sdegutis: partial works from the wrong direction for your code

10:38 sdegutis: Ahh right, I have to fill in the innards when I don't have them yet.

10:38 Olajyd: @justin_smith.. I’m sorry can’t find the compare function, is it the `move-up` function you wrote?

10:38 justin_smith: Olajyd: it's called "compare"

10:38 oddcully: ,(doc compare)

10:38 clojurebot: "([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"

10:38 justin_smith: Olajyd: I literally showed how to use compare right after you asked the first time

10:39 ,(compare (java.util.Date.) (java.util.Date. 0))

10:39 clojurebot: 1

10:39 justin_smith: that result means the first one was greater

10:39 Olajyd: @justin_smith I’m sorry i got disconnected when I asked the first time :)

10:39 justin_smith: oh, OK

10:40 I have joins/parts/disconnects turned off on this channel, it's too noisy otherwise

10:40 oddcully: Olajyd: there is also a log: http://clojure-log.n01se.net/

10:41 Olajyd: @oddcully Thanks for helping me out on saturday :)

10:42 oddcully: yw, but i forgot ;)

10:43 Olajyd: @oddcully : I have a vector of dates in the format (yyyy/MM/dd) and I want to be able to get the maximum date using `reduce`

10:43 justin_smith: Olajyd: you could also use max-key

10:43 gilliard: Olajyd: that date format will sort lexicographically, if they're strings.

10:44 justin_smith: , (apply max-key #(.getTime %) [(java.util.Date. 0) (java.util.Date. 1) (java.util.Date. 2)])

10:44 Olajyd: really @gilliard

10:44 clojurebot: #inst "1970-01-01T00:00:00.002-00:00"

10:44 justin_smith: Olajyd: the above will always return the largest date in a sequence

10:45 oddcully: dates in the "formst X" are just strings right?

10:45 justin_smith: oh, I thought you meant you had real dates (as in java.util.Date.)

10:45 gilliard: ,(max ["2015/5/2" "2015/11/10" "2010/20/9"])

10:45 clojurebot: ["2015/5/2" "2015/11/10" "2010/20/9"]

10:45 gilliard: ,(apply max ["2015/5/2" "2015/11/10" "2010/20/9"])

10:45 clojurebot: #error {\n :cause "java.lang.String cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers gt "Numbers.java" 229]}]\n :trace\n [[clojure.lang.Numbers gt "Numbers.java" 229]\n [clojure.lang.Numbers max "Numbers.java" 4027]\n [clojure.core$max invokeStatic "core.clj" 1091]\n ...

10:45 justin_smith: gilliard: first of sort

10:45 oddcully: shouldn't this be just be the last of a string sort?

10:45 gilliard: justin_smith: you got it ;)

10:45 justin_smith: oddcully: oh right, or first of a reversed sort

10:46 or a reduce using compare (compare works on strings)

10:46 oddcully: at least of MM/dd is actually used (leading zeros)

10:48 justin_smith: ,(reduce #(case (compare % %2) 1 % -1 %2 0 %1) ["1970/02/11" "1914/03/01" "0000/00/00"])

10:48 clojurebot: #error {\n :cause "No matching clause: 6"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching clause: 6"\n :at [sandbox$eval102$fn__103 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval102$fn__103 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.PersistentVector reduce "PersistentVector.java" 323]\n [clojure.core$reduce invokeStatic "core.clj" 6517]\n [clojure.core$re...

10:48 justin_smith: err

10:48 compare can return 6, OK

10:49 oddcully: `Returns a negative number, zero, or a positive number...`

10:49 gilliard: ye just 0, more than 0, or less than 0

10:49 justin_smith: ,(reduce #(if (pos? (compare % %2)) %1 %2) ["1970/02/11" "1914/03/01" "0000/00/00"])

10:49 clojurebot: "1970/02/11"

10:49 Olajyd: thanks @justin_smith :)

10:52 justin_smith: Olajyd: the funny part is that my initial answer still works even though I was wrong about your data type, because compare is just that general

10:52 Olajyd: @justin_smith the solution works for me

10:52 :)

10:52 oddcully: random fun wikipedia fact: on 1914-03-01 china joined the Universal Postal Union

10:54 justin_smith: haha

10:58 wes__: justin_smith Using your move-up works (move-up [f1 f2 f3] f2) => [f2 f1 f3] but (reduce [f1 f2 f3] '(f2 f3)) => [f1 f2 f3] where I expect [f2 f3 f1]

10:59 justin_smith: wes__: hmm

10:59 wes__: it works?

11:00 , (defn move-up [v i] (let [pos (.indexOf v i)] (if (pos? pos) (assoc v pos (v (dec pos)) (dec pos) i) v)))

11:00 clojurebot: #'sandbox/move-up

11:00 justin_smith: , (reduce move-up '[f1 f2 f3] '(f2 f3))

11:00 clojurebot: [f2 f3 f1]

11:04 wes__: justin_smith yeah, it works thanks. I just learned that '(f2 f3) is not the same as (list f2 f3)

11:05 justin_smith: oh, yeah :)

11:06 [f2 f3] works too - reduce can accept vectors, anything that seq works on

11:41 wes__: So, I got move-down working as well, but I discovered that the order of the items in the reduce function is important. How do I sort a seq by their index in a vector?

11:44 (sort #(.indexOf '[f1 f2 f3 f4 f5] %) '(f3 f5 f1))

11:45 justin_smith: ,(sort-by #(.indexOf '[f1 f2 f3 f4 f5] %) '(f3 f5 f1))

11:46 clojurebot: (f1 f3 f5)

11:46 jonathanj: hrm, how would i write a function that wraps another function and logs its arguments to a file? i tried: (defn log-to [path f] (with-open [fd (writer path)] (fn [s] (spit fd s) (f s))))

11:46 but i guess (with-open) closes as soon as log-to returns

11:46 justin_smith: jonathanj: yeah, only use with-open if you want to close the file in that block

11:47 jonathanj: otherwise you can use .write, and make your own arrangements to close the file...

11:47 wes__: Missed it by `that` much. thanks

11:47 justin_smith: wes__: yes, you were quite close

11:47 jonathanj: okay, well as a crappy interim measure i can just open the file and write to it everytime the inner function is invoked, how do i open a file for appending?

11:47 justin_smith: wes__: do you ever look at http://conj.io ?

11:48 jonathanj: it's an optional arg to writer

11:48 ,(doc clojure.java.io/writer)

11:48 clojurebot: "([x & opts]); Attempts to coerce its argument into an open java.io.Writer. Default implementations always return a java.io.BufferedWriter. Default implementations are provided for Writer, BufferedWriter, OutputStream, File, URI, URL, Socket, and String. If the argument is a String, it tries to resolve it first as a URI, then as a local file name. URIs with a 'file' protocol are converted to local...

11:48 wes__: justin_smith no. Thanks for showing it to me.

11:49 jonathanj: i'm reading the docs for writer but there is apparently no mention of what the arguments are?

11:49 justin_smith: wes__: I asked because with the way conj.io is layed out, you likely would have found sort-by :)

11:49 jonathanj: the optional arguments, i mean

11:49 justin_smith: jonathanj: hmm, I know they are around somewhere

11:49 jonathanj: looks like it's just :append

11:49 (looking at an example on conj.io)

11:50 justin_smith: jonathanj: source reveals it https://github.com/clojure/clojure/blob/master/src/clj/clojure/java/io.clj#L69

11:50 jonathanj: :append true, at least

11:50 justin_smith: jonathanj: useful site :)

11:51 jonathanj: what are the differences between conj.io and clojuredocs?

11:51 justin_smith: jonathanj: different maintainers, conj.io is more ambitious

11:51 jonathanj: how so?

11:52 justin_smith: it wants to document libs outside of clojure itself eventually

11:52 jonathanj: ah, nice

11:52 justin_smith: jonathanj: arrdem and andyf could probably tell you about the differences in more detail (they maintain the two sites)

12:00 jonathanj: i remember some clojure library that implemented a grammar-based parser based on BNF (or something that was really close to it), but i can't remember the name of the library

12:01 oh instaparse

12:01 justin_smith: instaparse?

12:01 blkcat: instaparse?

12:01 clojurebot: instaparse is lovely

12:01 instaparse is lovely

12:01 justin_smith: hahaha

12:01 blkcat: i use instaparse and can confirm that it rocks

12:01 justin_smith: ^ the beginning of a musical about parsing

12:01 (to the tune of "monorail" of course)

12:26 jonathanj: so if i have an instaparse rule like `word = letter+ <letter> = #'[a-zA-Z]'` i end up with :word ["h" "e" "l" "l" "o"]

12:27 it looks like the preferred way to turn that into a string is `(transform {:word str} ...)`?

12:27 i can't indicate this in the grammar some how?

12:28 sdegutis: I just used clojure.data/diff

12:28 and clojure.set/map-invert, I bet you didn't even know it existed!

12:30 jonathanj: the problem i guess is that (transform {:word str} ...) turns [:word ["h" "i"]] into "hi", i'd prefer not to destroy the tag

12:32 alex_engelberg: jonathanj: I'm missing context (just joined channel) but I may be able to help with your instaparse problem

12:32 jonathanj: alex_engelberg: hello!

12:32 alex_engelberg: firstly, instaparse is a wonderful piece of software, thank you very much

12:33 alex_engelberg: thank you! and thank YOU for using it! :)

12:33 sdegutis: My task this week is to write a parser via a purely immutable state machine.

12:34 alex_engelberg: I'm an IRC noob, is there a way to look at previous messages before I joined?

12:34 Or is the solution to just always stay logged in? :)

12:34 sdegutis: alex_engelberg: neither

12:34 arohner: alex_engelberg: yes, stay logged in. There are also bot loggers

12:34 sdegutis: http://logs.lazybot.org/irc.freenode.net/%23clojure

12:34 alex_engelberg: just use that link. only works for here.

12:34 jonathanj: alex_engelberg: i'd like not to destroy the tag being transformed

12:34 arohner: http://clojure-log.n01se.net/

12:34 oddcully: alex_engelberg: http://clojure-log.n01se.net/

12:34 sdegutis: arohner: I prefer lazybot's

12:34 alex_engelberg: Thanks

12:34 oddcully: alex_engelberg: and instaparse is fscking awesome!

12:35 jonathanj: alex_engelberg: (insta/transform {:word str} [:word "h" "i"]) ends up losing the structure

12:35 sdegutis: oddcully: instaparse has nothing to do with checking or interactively repairing filesystem consistency

12:35 alex_engelberg: jonathanj: you want [:word "hi"]?

12:35 jonathanj: i realise i can probably do something like {:word (put-the-tag-back :word str)} but i'd like to avoid repeating myself if it's possible

12:36 alex_engelberg: yes

12:36 alex_engelberg: You could cleverly write your grammar with extra layers that are transformed in different ways

12:36 word = word2

12:36 word2 = #'[a-z]+'

12:36 And just transform word2

12:36 jonathanj: so produce something like [:word [:letters "h" "i"]] and transform letters with str?

12:37 alex_engelberg: yes.

12:38 I don't know enough about instaparse innards to know how much slower that would make the parser. The "put-the-tag-back" transformer would be the best place to do that work, efficiency-wise. I'd say it's probably a negligible difference though.

12:39 jonathanj: i guess that could work

12:39 thanks

12:40 alex_engelberg: jonathanj: no problem

12:40 I'm seeing a potential bug with clojure.tools.reader and cljs.tools.reader.

12:41 (clojure.tools.reader/read-string "018") => null pointer exception

12:42 Note that this is an invalid octal number, and throws a more user friendly number format exception in clojure.lang.LispReader.

12:42 On cljs (and I'm not sure this is a bug or a feature), (cljs.tools.reader/read-string "018") => 18

12:42 In other words, invalid octal numbers are simply parsed as decimal.

12:45 For comparison, (clojure.tools.reader/read-string "017") => 15, and same with cljs

13:25 puredanger: you could use that as a really weird platform detector

13:26 Bronsa: alex_engelberg: definitely a bug

13:29 justin_smith: puredanger: heh, for when cljc is just too easy

13:34 Bronsa: alex_engelberg: fixed in tools.reader master

13:57 jonathanj: i know that ztellman's libraries aren't terribly popular here but can anyone suggest why i might want to use core.async over manifold streams?

13:58 justin_smith: jonathanj: what makes you think his libs are unpopular?

13:58 jonathanj: core.async is inherently "push", manifold can do push or pull

13:58 (that's one reason)

13:58 jonathanj: justin_smith: i just don't see a lot of conversation around them here

13:59 and the mailing lists are very low volume

13:59 well, the aleph list anyway, i don't even think there are lists for his other libraries

13:59 justin_smith: jonathanj: ztellman did a great talk at the last conj comparing manifold, core.async, and prismatic/graph that explains them all on a continuum of design

13:59 amalloy: jonathanj: higher volume than most other clojure libraries, which have no ML at all

14:00 jonathanj: justin_smith: oh that sounds pretty great, i don't suppose you have a link or title of the talk for me?

14:00 justin_smith: jonathanj: if you really want to understand how manifold relates to core.async, I'd check out that talk - it's on youtube

14:00 amalloy: justin_smith: i don't quite understand what you mean by core.async being push-only

14:00 justin_smith: $google ztellman manifold clojure conj

14:00 lazybot: [Clojure/conj 2014 Notes - Forays into simplicity] http://eigenhombre.com/clojure/2014/11/27/conj-notes/

14:00 amalloy: like you can only push things into channels, and you can only pull things out, right?

14:01 jonathanj: justin_smith: i'm guessing that's not the one?

14:01 justin_smith: jonathanj: it's on youtube, one moment

14:01 jonathanj: https://www.youtube.com/watch?v=1bNOO3xxMc0 ?

14:02 justin_smith: nope, that's from clojure/west

14:02 jonathanj: this one https://www.youtube.com/watch?v=3oQTSP4FngY

14:02 jonathanj: justin_smith: thank you

14:04 justin_smith: amalloy: I wish I could remember the concrete details (I should have made a blog post about this), I was making an app where a lazy-seq was abstracting over input from a core.async channel, and it was "buffering" an item at a time

14:05 amalloy: as opposed to waiting until you seq to <! an item?

14:05 justin_smith: amalloy: I actually talked to ztellman about why this happened, and the explanation ended up being that lazy-seqs were a "pull" abstraction, and core.async is a "push" abstraction

14:06 amalloy: yes, that i agree with

14:06 justin_smith: and manifold is more flexible (I ended up going another route entirely in our app though)

14:06 now I want to make a minimal example (another thing on my "get around to it" list)

14:08 jonathanj: in the first 2 minutes of both of those talks, ztellman says "we don't just write software to raise the ambient temperature of the room"... haha

14:44 eriktjacobsen: Any critiques / improvements on a pattern that will take a list of maps, search for partial duplicates and remove them? So perhaps matching dupes on 2-3 keys, with option to customize which item is picked as the final de-duped one?

14:44 This is what I came up with: (defn remove-dupes [key-fn sort-fn compare-fn items]

14:44 (->> (group-by key-fn items)

14:44 (map (fn [[_ entries]]

14:44 (first (sort-by sort-fn compare-fn entries))))

14:44 (remove nil?)

14:44 flatten))

14:44 oddcully: first concern: not using refheap, pastebin, ...

14:45 eriktjacobsen: http://pastebin.com/EDpr1pHy

14:45 Will remember

14:45 oddcully: cool

14:46 justin_smith: eriktjacobsen: you may want to use group-by, if you have a function that will return the same result for all maps that should be considered dups (maybe select-keys ?)

14:47 ,(group-by #(select-keys % [:a :b]) [{:a 0 :b 1 :c 2} {:a 1 :b 1 :c 2} {:a 0 :b 1 :c 42}])

14:47 eriktjacobsen: group-by is the first call actually, I’m often passing in something like “#(clojure.string/join "-" ((juxt :partner :year :month) %))”

14:47 clojurebot: {{:a 0, :b 1} [{:a 0, :b 1, :c 2} {:a 0, :b 1, :c 42}], {:a 1, :b 1} [{:a 1, :b 1, :c 2}]}

14:48 eriktjacobsen: Oh I don’t have to string that / join do I… interesting right

14:48 amalloy: first of sort is not right in many scenarios; are you sure you can't use max-key?

14:48 justin_smith: right, you can use anything as a key in clojure

14:48 sdegutis: I'm back.

14:49 justin_smith: eriktjacobsen: also, use mapcat identity instead of remove nil / flatten

14:49 it replaces both, and is better behaved

14:49 eriktjacobsen: amalloy: I was intending to sometimes pass in something as simple as pulling an integer key and using < or > as compare, but also wanted to pass in ability to use a string or regex type compare to sort them…. so max-key would seem to force that

14:51 I’ll look into that (actually the remove nil / flatten I think is un-needed since this one does first, which will always return a record) this was actually from separate version that instead of outputting list of de-duped, it instead gave list of stuff to REMOVE (so I did a (when (> (count %) 1) (rest items))

14:51 Will do that though since I need both version

14:52 hellofunk: are bitwise operations supported on 64bit integers in clojure

14:53 eriktjacobsen: justin_smith: I dont think I knew that… could you explain how mapcat identity removes nils ? isn’t (identity nil) = nil? I would expect a single nil in the output

14:54 hiredman: eriktjacobsen: it is, he meant apply concat

14:55 or just turn the map in to a mapcat if the function returns nil or a collection

14:56 eriktjacobsen: hiredman it does actually work though… it flattens and removes the nils. I just dont understand why. http://pastebin.com/ArDbeyyW

15:00 oh duh concat doesn’t concat nils…. totally forgot. that seems like odd behavior though. interesting though

15:02 Thanks amalloy justin_smith. Learn something new everyday

15:05 TEttinger: hellofunk: yes. I think the default is to use long (64-bit signed) integers

15:05 kwladyka: REPL can affect memory usage in some way?

15:05 instead of running directly from jar file?

15:05 TEttinger: ,(bit-or (bit-shift-left 0xFFFFFFFF 15) 0xFFFFFFFF)

15:05 clojurebot: 140737488355327

15:06 kwladyka: what i see yes, but i am not sure

15:06 TEttinger: kwladyka: yeah, the REPL has to store previous evaluated arguments as *1, *2, *3 etc.

15:07 kwladyka: is a way to test app usage memory without compile it to jar?

15:08 TEttinger: I think it also needs to compile code differently, but I'm not sure how. jar (or uberjar for executables, or whatever war/uberwar stuff EE webdev needs) should probably be the default when testing performance if you're deploying that way

15:11 (I think it's likely that running a jar with the right memory settings, -Xms64m to start small and garbage collect quickly if not using all of the allocated memory, -Xmx512m or whatever the max you might need and can support is, mess with GC options, make sure you're using --server if you need speed, --client may help with memory at the expense of speed...)

15:11 or is it -server

15:12 anyway, running a jar with the right memory settings is very different from running a jar with very wrong memory settings

15:12 -Xms16G

15:12 "why is my jarva using so much rams?"

15:13 kwladyka: TEttinger, i use profiler to check memory usage so i see not only how many is allocated, but how many is really used

15:13 but as i see REPL affect results as i see

15:13 but i am not sure, i am researching it now :)

15:15 it can be noob question, but.. if i will do lein compile can i run app without doing lein uberjar?

15:15 TEttinger: I'm guessing uberjar is pretty slow for your project?

15:16 $google leiningen faster

15:16 lazybot: [Faster · technomancy/leiningen Wiki · GitHub] https://github.com/technomancy/leiningen/wiki/Faster

15:17 TEttinger: clojurebot: slow |no| more! https://github.com/technomancy/leiningen/wiki/Faster

15:17 clojurebot: You don't have to tell me twice.

15:17 TEttinger: ~slow

15:17 clojurebot: slow no more! https://github.com/technomancy/leiningen/wiki/Faster

15:17 sdegutis: I'm back again.

15:18 TEttinger: your nick is an anagram for degu sits. degus are kinda cute little creatures.

15:19 Bronsa: sdegutis: you don't have to announce it everytime

15:19 sdegutis: Bronsa: Phew, thanks.

15:20 TEttinger: Bronsa: I'm here currently

15:20 oddcully: ~logs

15:20 clojurebot: logs is http://clojure-log.n01se.net/

15:21 oddcully: ah i knew it

15:21 TEttinger: sdegutis: they're a pretty good thing to have in your name. https://en.wikipedia.org/wiki/Degu#/media/File:Octodon_degus_-Artis_Zoo,_Netherlands-8b.jpg

15:21 amalloy: sdegutis just needs like one more letter to have a lot of fun anagrams

15:21 duet siege

15:22 sdegutis: Oh man. Do I need to go back to /nick sed-utils?

15:22 TEttinger: Degus are extremely intelligent and have a good ability to solve problems. well there you go!

15:32 sdegutis: Is there a way to check if every item in a collection is equal besides (apply = coll) ?

15:33 amalloy: sure, there are lots of worse ways

15:33 gfredericks: what don't you like about (apply = coll)?

15:33 kwladyka: something is wrong with my profile file? https://www.refheap.com/58124c0debd9118eb4c6e7ab3 Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method.

15:33 amalloy: gfredericks: i'll tell you what *i* don't like about (apply = coll)

15:33 but i bet you already know: it doesn't work on empty colls

15:34 gfredericks: I didn't know that would be it

15:34 amalloy: (i regard this as a bug in = but nobody really cares)

15:34 gfredericks: but I think I might understand why it does

15:34 opqdonut: yeah (=) should be true

15:34 I agree

15:34 gfredericks: ,(<)

15:34 clojurebot: #error {\n :cause "Wrong number of args (0) passed to: core/<"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: core/<"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 399]\n [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 i...

15:34 opqdonut: (<) is less well defined than (=)

15:34 gfredericks: why is that?

15:35 opqdonut: or that's my knee-jerk reaction anyway, let me think

15:35 amalloy: gfredericks: last time this came up somebody claimed it is a little bit awkward if you extend this to the < family of functions, because then < and (complement >=) are no longer the same

15:35 but on reflection this is totally bunk, because they're already not the same on anything but 2 arguments

15:36 opqdonut: indeed

15:36 ok, I guess (=) and (<) are actually pretty symmetric. if you have the n-ary versions you should also have the 0-ary version

15:36 gfredericks: I've always thought of these arities as being related to recursive definitions of the functions

15:37 + and * can get all the way to 0 args because they are monoids

15:37 (in contrast with / and -)

15:37 sdegutis: What's the opposite of some

15:38 gfredericks: and and or are also monoids I think?

15:38 amalloy: gfredericks: yes, they are

15:38 gfredericks: so you can't get 0 args for = and < just by the monoid reasoning, it'd have to be something else

15:38 amalloy: gfredericks: the problem is that some and every? do extend down to empty collections, and (apply = coll) "should" be the same as (every? #(= % (first coll)) coll)

15:38 hiredman: well

15:39 gfredericks: in haskell that'd throw an exception

15:39 amalloy: gfredericks: i don't think so

15:39 gfredericks: for an empty list

15:39 amalloy: no, because every undefined [] = true

15:39 True

15:39 gfredericks: well arguably that has more to do with how the code is structured

15:40 if you wrote it (let [x (first coll)] (every? #(= % x) coll))

15:40 amalloy: gfredericks: still would work fine in haskell, because lazy

15:40 gfredericks: I feel like this is a meaningful point somehow

15:40 amalloy: you can't make that throw, because you can't possibly use the value if the list is empty

15:40 sdegutis: Is there a shorter way of (not (some f xs)) ?

15:40 gfredericks: amalloy: sure but the language being lazy is a side detail here

15:41 sdegutis: not-any?

15:41 sdegutis: Ahhh.

15:41 Silly lack of consistent naming.

15:41 amalloy: i don't think so. if you're claiming that my proposed equivalent would throw an exception in haskell, it seems like the way haskell behaves is pretty relevant

15:41 sdegutis: Earlier I looked for any? and couldn't find it. Turns out it was some.

15:41 kwladyka: seriously what am i doing wrong with lein uberjar, why am i gettign this error? All looks like is should in poject.clj https://www.refheap.com/58124c0debd9118eb4c6e7ab3

15:41 opqdonut: sdegutis: because it returns non-booleans too

15:41 Bronsa: sdegutis: any? would imply a boolean return.

15:41 gfredericks: amalloy: I'm appealing to one part of the behavior of haskell and not the other part :P

15:42 opqdonut: but yeah it trips people up

15:42 sdegutis: Ahhh right, Clojure makes types multi-task.

15:43 amalloy: gfredericks: so your argument seems to be that in two consistently-defined languages, my suggested identity would hold, but in a theoretical bad language that's a mix of both, a restructured version of my identity would throw an exception

15:43 (eg, in java you would be right)

15:43 gfredericks: so let's think about it recursively

15:44 if you add another element to an = expression, the expression is true if that element equals the "first" element in the expression and if the rest of them are equal

15:44 i.e. (= a b1 b2 ...) is (and (= a b1) (= b1 b2 ...))

15:44 and the base case is that (= bn) is true

15:44 sdegutis: Thanks gfredericks.

15:45 gfredericks: my point is that the natural base case in this formulation is 1 arg

15:45 and this works for all the ordering predicates

15:45 sdegutis: What's a striking way to test if coll contains :a or :b (or both)?

15:46 gfredericks: so adding a 0-arg version feels like an unrelated "alternate base case" or something

15:46 sdegutis: (some #{:a :b} coll)

15:46 sdegutis: Amazing.

15:46 Thanks gfredericks. You won twice in a row.

15:46 kwladyka: oh i have to use :gen-class ...

15:48 amalloy: gfredericks: doesn't apply to not=, right?

15:48 gfredericks: ,(doc not=)

15:48 clojurebot: "([x] [x y] [x y & more]); Same as (not (= obj1 obj2))"

15:49 gfredericks: (not= a b1 b2 ...) is (or (not= a b1) (not= b1 b2 ...))

15:49 ,(not= 42)

15:49 clojurebot: false

15:49 gfredericks: and the base case is (not= bn) is false

15:49 I just did that off the top of my head, hadn't thought about not=

15:49 so not sure if it makes sense

15:50 amalloy: I think a better approach to what I was trying to say w/ haskell would be "You can't formulate it that way mathematically"

15:51 e.g., with set theory

15:51 * gfredericks knows that sets cannot contain equal elements

15:58 hiredman: isn't equivalence in math a binary operation?

15:58 err

15:58 relation

15:58 gfredericks: yeah

15:59 that doesn't stop you from making it variadic though

15:59 the question is does it make sense to have the (=) base case when you do

15:59 hiredman: does it make sense to have a base case (= b) ?

15:59 gfredericks: I think it makes as much sense as (+)

16:00 and I think (=) makes less sense

16:00 that's the side I'm arguing for anyhow

16:00 not gonna get in a fight about it

16:00 hiredman: and if (= b) makes sense even if = is a binary relation, then why doesn't (=) make as much sense?

16:01 gfredericks: well that's what I was trying to argue; in particular I think (+) => 0 is a "natural" base case for + and that (= b) => true is a "natural" base case for =

16:01 because they both have nice recursive definitions that use those base cases

16:01 I don't know of a recursive definition for = that uses (=) true as a base case

16:04 justin_smith: gfredericks: I guess there is (apply = c), which should return true if c is nil / empty

16:05 intuitively at least

16:05 amalloy: justin_smith: that was the base case of this discussion

16:05 justin_smith: amalloy: d'oh! shows me for replying before I catch up on the scrollback

16:06 amalloy: it seeems like gfredericks is arguing that the usual description of (apply = xs) as "are all the things in xs equal to each other" is incorrect

16:06 because if you take that description it is obvious that (=) is true

16:07 hiredman: gfredericks: that is an interesting point

16:07 sdegutis: Thanks for all your help.

16:07 gfredericks: amalloy: I might argue that that english phrasing is a bit ambiguous about what the empty case means

16:07 dunno maybe not

16:07 english hard

16:08 kwladyka: used PS old gen <- if i have something like that in my app with 209 MB in profiler... what is it mean? Am i doing something wrong?

16:08 it is about memory

16:09 amalloy: i just realized i don't have to put up with this sass. i can just +b gfredericks

16:09 gfredericks: o_O

16:09 amalloy: it will be as foretold in the prophecies by andyf. amalloy will rule with an iron fist

16:10 hiredman: there exists an equivalence class E for all item x in list l where x is a member of E

16:12 gfredericks: hiredman: quoting from some formalization of something?

16:12 hiredman: no, trying to piece one together

16:13 that seems to be a statement of equality which would allow for (=), but I forget all that stuff about which binders → existence of whatever

16:13 kwladyka: ech i totally don't know how to get conclusions from profiler :/

16:19 justin_smith: kwladyka: you could see if the allocated size gets bigger if you run the code twice, you could profile subprograms to try and narrow down what is allocating

16:19 hiredman: the tricky thing is, I don't think any language has first class equivalence classes, but you can define one given at least one member of the equivalence class and some kind of equality operator

16:20 (which of course is circular, we are trying to define equality)

16:20 so you end up with recursion that bottoms out with a single element

16:22 kwladyka: justin_smith, https://www.dropbox.com/sh/fekagh9kp77f057/AAC0dCeunm2MDt0qWRw8f4lda?dl=0 look at clojure-jar char vs scala char

16:23 justin_smith, in both i did 10 sec sleep before

16:23 justin_smith, both do the same...

16:23 justin_smith, i totally stack with that, i dont know how to get conclusion what is wrong

16:24 just no idea what to do now to solve that :/

16:26 justin_smith: ugh, what a terrible gallery

16:26 kwladyka: sorry, i dont know better to fast upload

16:27 oddcully: haha

16:27 justin_smith: kwladyka: it's OK, you didn't implement that gallery view, but it's terrible

16:27 kwladyka: justin_smith, :)

16:28 justin_smith: the biggest difference there is that with clojure you have the whole compiler and all its libs in heap, with scala you do not

16:28 kwladyka: why the same algorithm in scala is so fast and consume so less memory, it makes me sick

16:28 justin_smith: but that isn't going to cause your speed problem

16:29 kwladyka: justin_smith, but clojure-jar.png is for uberjar file

16:29 justin_smith: uberjar has the entirety of clojure in it

16:29 there is no standalone option with clojure, unlike scala

16:29 the feature simply doesn't exist

16:29 Bronsa: (inc puredanger) ;; thanks for CLJ-1093

16:29 lazybot: ⇒ 62

16:30 puredanger: did you catch the outcome?

16:30 justin_smith: but the extra ram used by clojure itself is not the cause of your speed difference, beyond the few seconds it takes clojure to bootstrap itself

16:30 kwladyka: justin_smith, do you know what used PS old gen can mean? maybe if you will see the code?

16:30 justin_smith: kwladyka: I've looked at your code already, it's complicated and I have my own hard debugging to do

16:30 sorry

16:30 kwladyka: justin_smith, because of about 10 sec sleep before counting it shouldnt affect the time

16:31 justin_smith, but didnt see any technical anti-performance code? :)

16:32 Bronsa: puredanger: yes. not exactly what I was hoping for but I'm fine with it, it's consistent with the doc and CLJ-1460

16:32 puredanger: Bronsa: he also addressed your other question on the (defn ^{:tag foo} a [])

16:32 Bronsa: yup saw that too

16:32 kwladyka: justin_smith, any hints what more can i do t solve that? i dont have more ideas....

16:33 justin_smith: kwladyka: I've looked at your code multiple times already, I suggested the things I thought might be issues, but I really can't fix this performance issue for you

16:33 kwladyka: is it possible it is because of Clojure, not my bug? Just Clojure do this longer or something like that?

16:34 TimMc: gfredericks: Regarding (=), I like the invariant that remving an element from the input never turns the output from true to false.

16:34 kwladyka: justin_smith, each time code was improved, i did big step, but now i stack totally what can i do more, i rewrited algorithm to work like this one in scala, but even now performance is much worst

16:35 justin_smith: kwladyka: if you switch some of your data from vanilla hash-maps to defrecords (which are in most ways identical in behavior to hash-maps, so it won't be a big change to your code) the profiler might give you easier to use data

16:35 TimMc: gfredericks: Or put more generally, "= returns true iff no two inputs are unequal" -- and if there are no two inputs, it is vaciously true.

16:35 *vacuously

16:35 kwladyka: justin_smith, anyway thank you so much for trying help me with that problem.

16:35 puredanger: Bronsa: meaning it now has behavior prior to direct linking

16:36 kwladyka: justin_smith, defrecords performance is better?

16:37 justin_smith: kwladyka: it shows up as a different datatype in your profiler

16:37 thus you can see where all that ram is going

16:37 kwladyka: justin_smith, oh

16:37 justin_smith: like which kind of object is being created to such excess (if that is in fact the issue). Also try CPU profiling, see which methods are doing the most work.

16:39 kwladyka: it is hard to say what is the problem, but for sure it consume too much memory vs scala solution

16:39 hiredman: https://gist.github.com/hiredman/2aa99f1c24634e0fd9de

16:39 Bronsa: puredanger: I think there's still a difference but it's probably not meaningful

16:40 kwladyka: i mean if it is CPU problem, shouldnt be....

16:40 CPU didnt cross 80% during all counting

16:40 justin_smith: kwladyka: I already told you why the ram usage is different, clojure loads the full compiler into your app at runtime, scala does not

16:41 sdegutis: For anyone here looking to practice Clojure or sharpen their Clojure skills, this is an excellent Java file for porting to pure Clojure using every Clojure technique in the book to shorten it by a huge degree: https://raw.githubusercontent.com/slagyr/latlngtz/master/src/latlngtz/TimezoneMapper.java

16:41 hiredman: so if any language had first class equivilance classes, it would be natural to define equality using them in a way where (=) would work, but having first class ecs seems very impractical, so what is left is the recursive definition of = which relies on (= b) working

16:41 oops, deleted the wrong line (emacs repeats my inputs)

16:42 kwladyka: justin_smith, yes but anyway it consume too much memory, i am afraid it is connected with Used PS old gen, it can be some track, but i dont understand what it is :)

16:42 what can cause that

16:43 but maybe it is not my code but Clojure...

16:43 hiredman: and since you need a base case for (= b) adding another for (=) seems inelegant

16:43 Bronsa: puredanger: actually I'm not sure rettag is very useful right now? it seem to only accept stuff like (defn ^long x [] ..) which don't make sense at runtime since long is evaluated to #<clojure.core$long..>

16:44 I'll try to look into it if I have some time tomorrow and let you know

16:45 gfredericks: hiredman: "Do all these elements belong to one class?" ← doesn't make sense for no elements

16:46 hiredman: gfredericks: https://en.wikipedia.org/wiki/Universal_quantification#The_empty_set

16:46 justin_smith: kwladyka: if I start clojure.jar, with no other libs loaded (not even lein or nrepl) I see a vsz/rss of 7056368 86412

16:46 that's a baseline, it won't go smaller

16:47 gfredericks: hiredman: I'm talking about (->> coll frequencies count (= 1))

16:47 or group-by if you like

16:48 kwladyka: justin_smith, i am thinking more about maybe Clojure remember some outputs for some magic reasons

16:48 cash that for future for me :)

16:49 xificurC: hiccup, garden, sablono - all these are used to generate html/css on the fly? I thought the purpose is to have it defined in clojure, process the definitions and generate static files. Am I misinterpreting something here?

16:50 hiredman: sure, right, you can obviously write the code differently, and via church-turing and get something in some other logic that will do the same

16:50 justin_smith: xificurC: static is relative, you can make a compile time step that outputs your resources if there is no relevant run time input

16:51 kwladyka: xificurC, http://clojure.wladyka.eu/posts/2015-06-01-template-libraries.html you can read my opinion about template libraries

16:52 gfredericks: hiredman: maybe I'm just having trouble connecting (=) to equivalence classes; how do you phrase the question that (=) is asking in terms of equivalence classes?

16:53 hiredman: gfredericks: set theoretic notions of equality seem to be based on equivalence classes

16:54 (seem to meaning I am not sure my understanding is correct, not casting doubt on the field)

16:54 xificurC: justin_smith: I see, although since there's no utility functions/macros written for this I take it it's not very common to do that

16:55 doesn't computing the page hinder performance on the server?

16:55 kwladyka: thanks, although it seems very biased

16:56 hiredman: so I guess I don't see the argument from some formalism that handling (= b) is valid but (=) is not

16:56 kwladyka: xificurC, because it is my opinion base on my own experience :)

16:57 amalloy: justin_smith: most of that vsize is mmapped files though, not taking up any real memory if other programs need it

16:58 well, i don't know about "most". but a lot of

16:58 hiredman: structurally (= b) makes more sense, because it is a base case you need in this case, but why not handle a base case for (=) if it would make it easier for client code

17:00 gfredericks: hiredman: yeah I'm not saying clojure shouldn't change necessarily; though you might argue that all the theoretical hand-waving suggests that anybody calling (=) has a high probability of having done it by accident. but that's probably not true

17:00 should (not=) be false?

17:01 xificurC: impressive how 1 guy (weavejester) created so many well known web-related libraries, e.g. ring, compojure, hiccup

17:01 kwladyka: xificurC, yes but i guess he didnt do this alone

17:02 _guess_

17:02 hiredman: gfredericks: I dunno

17:02 I guess? is there a reason it shouldn't be the negation of =?

17:03 gfredericks: well the argument for (=) seems to be "well *I* think it's obvious what it means" so I wondered if not= was the same way

17:03 where *I* isn't anybody in particular

17:03 hellofunk: TEttinger: i get an int out of range error if i try to go beyond 32 bits

17:04 hiredman: equality is very problematic

17:04 I taught clojurebot a factoid about scala years ago, that was a quote from someone in #scala saying something like "we are so screwed on ="

17:04 TEttinger: hellofunk: code please

17:05 hiredman: I must owe that guy a beer

17:05 slester: hmm, splitting up my code is proving a bit difficult

17:05 gfredericks: hiredman: haha

17:05 hellofunk: actually the error is java.lang.IllegalArgumentException: Value out of range for int: 4294967295

17:05 TEttinger: cooooode please

17:05 are you calling int on a large number?

17:06 hiredman: ~scala

17:06 clojurebot: scala is val foo = bar ~-> 45 <~< "Fred" %% x

17:06 TEttinger: use long if you need a 64-bit signed integer

17:06 slester: Do a lot of people have just one giant file with all the functions in it? Seems bad, but I can't separate them into namespaces because basically all the functions call each other

17:06 TEttinger: ,(int 4294967295)

17:06 clojurebot: #error {\n :cause "Value out of range for int: 4294967295"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Value out of range for int: 4294967295"\n :at [clojure.lang.RT intCast "RT.java" 1198]}]\n :trace\n [[clojure.lang.RT intCast "RT.java" 1198]\n [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "...

17:06 TEttinger: ,(long 4294967295)

17:06 clojurebot: 4294967295

17:07 hellofunk: TEttinger: ah, i see the problem now. it's the API i'm using that is apparently limited to 32 bits under the hood. if i do it at the repl, no problem over 32 bits

17:08 the stack trace reveals an intCast right before the out of range error

17:08 TEttinger: slester: that's a pretty general architecture problem. from my experience, games are particularly susceptible to architecture issues because of the need to have so many things affect the inherently mutable graphics code.

17:08 hefesto: Hi. I am new at Clojure and irc... so I'm doing this the right way (if not, please say so). I am trying to use clj-antlr (https://github.com/aphyr/clj-antlr) on a project, but I keep getting java.io.FileNotFoundException: Could not locate clj_antlr__init.class or clj_antlr.clj on classpath: , compiling:(date.clj:1:1). On project.clj I add the [clj-antlr "0.2.2"] dependency and lein repl shows the previous error. ¿Does anyone see what I'm doing wro

17:08 ng?

17:08 TEttinger: hey hefesto

17:09 hefesto: so *I hope* I'm doing this the right way

17:09 slester: TEttinger: yeah... :( I'm not sure what I can do about it though.

17:09 TEttinger: what are you requiring the clj-antlr dep as in your date.clj file?

17:09 hefesto: yes

17:09 (ns com.bm.bmi.date

17:09 "Parse dates using DateExpr.g4 grammar and ANTLR"

17:09 (require ['clj-antlr.core :as 'antlr]))

17:09 xificurC: paste your date.clj into a pastebin

17:10 hefesto: (ns com.bm.bmi.date

17:10 "Parse dates using DateExpr.g4 grammar and ANTLR"

17:10 (require ['clj-antlr.core :as 'antlr]))

17:10 (defn foo

17:10 "I don't do a whole lot."

17:10 [x]

17:10 (println x "Hello, World!"))

17:10 xificurC: hefesto: you're new to IRC, don't do that :)

17:10 TEttinger: hefesto:

17:10 ~pastebin

17:10 clojurebot: pastebin how about refheap? https://www.refheap.com/

17:10 hefesto: ok.

17:10 sorry

17:10 xificurC: if you have more than 1 line of code use a site to paste your code

17:11 hefesto: okay, sorry.

17:11 TEttinger: your require is incorrect for an ns

17:11 within the ns form, (:require [clj-antlr.core :as antlr])

17:12 you still need to have the parens match, I just did that one section of the 3rd line in the date

17:12 hefesto: I see

17:12 TEttinger: (require ['clj-antlr.core :as 'antlr]) ; this is correct if you're running it at the REPL, or in any part of a file that isn't the ns macro

17:13 xificurC: or (require '[clj-antlr.core :as antlr])

17:13 TEttinger: there's an in-depth guide here, hefesto http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

17:14 (inc xificurC)

17:14 lazybot: ⇒ 1

17:14 hefesto: thank you very much!!!

17:14 TEttinger: no prob, is it working?

17:14 xificurC: seems like (bad joke ahead) I'm the One

17:15 TEttinger: maybe in the next life

17:15 hefesto: repl started to work

17:15 which i've been trying to do for a while

17:15 so it's a huge success for just now.

17:16 :)

17:16 TEttinger: woo

17:16 you're using lein repl , right?

17:16 hefesto: emacs cider right now

17:18 TEttinger: I'm always kinda disappointed how the official docs don't really say "use lein, please, it's the best way right now" when talking about project management. I don't use emacs, but I think the clojure tools for it all use lein internally for projects and deps?

17:18 there's boot, which is really meant for larger projects it seems from their site

17:24 Bronsa: puredanger: yeah I looked into it and it doesn't seem like rettag makes sense the way it is implemented now. it will only accept (defn ^long x ..) or (defn ^double x ..) but those are invalid tags

17:26 hefesto: <TEttinger> : I dont know what emacs use internally. I've tried it out with the lein repl and the error disappeared too :)

17:27 TEttinger: woo

17:29 puredanger: Bronsa: thx

17:31 michaniskin__: TEttinger: cider should work fine with boot btw

17:32 TEttinger: nice

17:32 michaniskin__: but for beginners lein is probably a better alternative because there is a lot of stuff on stackoverflow to copy/paste from

17:32 which is pretty important if you're just learning the language

17:32 TEttinger: I just think boot makes sense as a thing to transition to if a project becomes unmanageable with lein. is boot able to produce uberjars?

17:32 michaniskin__: sure

17:33 it can do all the things you need

17:33 TEttinger: (is it faster at compiling at lein? pretty please?)

17:33 michaniskin__: haha no, boot is more about correctness and sanity

17:33 TEttinger: pfft

17:33 you know what I just wrote?

17:33 michaniskin__: so aggressive caching isn't done unless we have a solid way to invalidate cache

17:34 TEttinger: [DllImport("xbrz.dll", EntryPoint = "scale")] internal static extern int scale(int factor, UIntPtr src, UIntPtr trg, int srcWidth, int srcHeight, int colFmt, IntPtr nil = default(IntPtr), int yFirst = 0, int yLast = int.MaxValue);

17:35 michaniskin__: however, i think boot is a lot better for incremental compiles because of how it's organized, so that's what you generally use instead of persistent caches

17:35 justin_smith: ~.

17:35 clojurebot: Cool story bro.

17:35 TEttinger: justin_smith: ?

17:36 justin_smith: TEttinger: that's the magic key sequence that closes ssh when it hangs

17:36 TEttinger: ~~

17:36 clojurebot: Titim gan éirí ort.

17:36 justin_smith: TEttinger: my ssh connection to my irc session hangs when I connect from work

17:36 TEttinger: clojurebot: ~ is how you get factoids from me

17:36 clojurebot: You don't have to tell me twice.

17:37 TEttinger: ~~

17:37 clojurebot: ~ is how you get factoids from me

17:37 justin_smith: in this instance I had pushed page-up, and hit ~. because the page up was not scrolling. Turns out the ~. only works immediately after newlines

17:37 TEttinger: aw

18:21 sdegutis: Given [:a :b :c :d :e], what's a spectacular way to generate [[:a []], [:b [:a]], [:c [:a :b]], [:d [:a :b :c]], [:e [:a :b :c :d]]] ?

18:26 {blake}: sdegutis: Beat the CPU till it catches fire. Have the answers on a slip of flash paper in your pocket.

18:27 michaniskin__: ,(reduce #(conj %1 (conj [%2 (vec (flatten (reverse (last %1))))])) [] [:a :b :c])

18:27 clojurebot: [[:a []] [:b [:a]] [:c [:a :b]]]

18:27 sdegutis: Hmm we may have a tie.

18:28 Both very good answers so far. But none quite spectacular... yet!

18:28 {blake}: I'd probably use a for.

18:28 justin_smith: ,(first (reduce (fn [[acc prev] e] [(conj acc (vector e prev)) (conj prev e)]) [[][]] [:a :b :c :d]))

18:28 clojurebot: [[:a []] [:b [:a]] [:c [:a :b]] [:d [:a :b :c]]]

18:29 justin_smith: sdegutis: ^

18:29 sdegutis: I like the [[][]] in justin_smith's solution.

18:29 But still not spectacular.

18:29 {blake}: Nice.

18:30 Write a macro that, when you start typing [:a :b...] it responds with "I see where you're going with this." and gives the result.

18:31 justin_smith: ,(first (reduce (fn [[acc prev] e] [(conj acc [e prev]) (conj prev e)]) [[][]] [:a :b :c :d]))

18:31 clojurebot: [[:a []] [:b [:a]] [:c [:a :b]] [:d [:a :b :c]]]

18:34 sdegutis: {blake}: Haskell basically has that.

18:34 {blake}: heh

18:34 (inc Haskell)

18:34 lazybot: ⇒ 2

18:36 DerGuteMoritz: here's one without reduce: (let [x [:a :b :c :d :e]] (mapv vector x (map (comp vec drop-last) (range (count x) 0 -1) (repeat x))))

18:36 sdegutis: take 10 $ ['a','b' ..] // => "abcdefghij" (inc Haskell)

18:36 DerGuteMoritz: ugh, that's the one I was working on

18:37 cept I got distracted by magNITED states of merica

18:37 that rant was priceless

18:37 {blake}: Eh. I like justin_smith's better.

18:38 sdegutis: I'm still trying to understand DerGuteMoritz -- that in itself is major points!

18:38 Anyway thanks for always doing the hard parts of my day job for me you guys.

18:38 Especially you justin_smith.

18:38 DerGuteMoritz: heh yeah it's not exactly what I would use in production code

18:38 sdegutis: DerGuteMoritz: you'd be surprised how much FP is in production code

18:39 michaniskin__: ,((fn [x] (zipmap x (mapv #(vec (take-while (partial not= %) x)) x))) [:a :b :c :d])

18:39 clojurebot: {:a [], :b [:a], :c [:a :b], :d [:a :b :c]}

18:39 DerGuteMoritz: just wanted to do one without reduce for a change

18:39 justin_smith: DerGuteMoritz: on a vector, never use drop-last, use pop instead

18:39 michaniskin__: derp

18:39 justin_smith: DerGuteMoritz: oh wait, that isn't a vector coming in, neverm ind

18:39 sdegutis: I need to loop over each item in a coll while testing against all previous elements in the same coll each time.

18:39 This is the most spectacular way to do it.

18:40 {blake}: michaniskin__: Oh, also nice.

18:40 DerGuteMoritz: justin_smith: also, pop doesn't take an argument of how many elements to pop - but we could use subvec instead perhaps

18:41 (when first mapping to vectors, right)

18:41 sdegutis: Still struggling to figure out how in the world DerGuteMoritz's solution works.

18:42 DerGuteMoritz: sdegutis: try this as a first step: (map drop-last (range (count x) 0 -1) (repeat x))

18:43 justin_smith: sdegutis: after you recall map is varargs, it's easy

18:43 DerGuteMoritz: the rest is just decoration ;-)

18:43 sdegutis: justin_smith: That's the fact I was planning to take advantage of actually.

18:43 In my try, all I got so far was ##(map vector (reverse coll) coll)

18:43 lazybot: java.lang.RuntimeException: Unable to resolve symbol: coll in this context

18:44 sdegutis: I mean ##(let [coll [:a :b :c :d :e]] (map vector (reverse coll) coll))

18:44 lazybot: ⇒ ([:e :a] [:d :b] [:c :c] [:b :d] [:a :e])

18:44 sdegutis: I was gonna work from there.

18:44 And that's when I found this: https://www.youtube.com/watch?v=1L3eeC2lJZs

18:44 michaniskin__: iterate is the spectacularest

18:45 sdegutis: Which really slowed my progress down on the solution.

18:49 DerGuteMoritz: michaniskin__: hm nice idea

18:50 eblood: i have an uberjar that’s configured to start a main function that starts a backend process (started with java -jar dt-utils.jar).. i want to hop into a repl to use a function to test something, so using “java -cp dt-utils.jar clojure.main” I can get a repl, but none of the namespaces are initialized. what else do i need to do?

18:50 justin_smith: eblood: require your core namespace

18:50 eblood: remember that require from the repl is different from in ns forms

18:51 michaniskin__: ,((comp (partial apply map vector) (juxt identity (comp reverse (partial take-while first) (partial iterate pop) pop))) [:a :b :c :d])

18:51 clojurebot: ([:a [:a]] [:b [:a :b]] [:c [:a :b :c]])

18:51 michaniskin__: hehe

18:51 DerGuteMoritz: (let [x [:a :b :c :d :e]] (map vector x (cons [] (reverse (take (count x) (iterate pop x))))))

18:52 justin_smith: (inc michaniskin__)

18:52 lazybot: ⇒ 1

18:52 justin_smith: that's a nice one

18:52 (inc michaniskin)

18:52 lazybot: ⇒ 2

18:52 michaniskin__: i want my family coat of arms to have COMP JUXT PARTIAL APPLY in the crest

18:52 DerGuteMoritz: ,(let [x [:a :b :c :d :e]] (map vector x (cons [] (reverse (take (count x) (iterate pop x))))))

18:52 clojurebot: ([:a []] [:b [:a]] [:c [:a :b]] [:d [:a :b :c]] [:e [:a :b :c :d]])

18:52 sdegutis: My plan was to first turn [:a :b :c :d :e] into [[] [:a] [:a :b] [:a :b :c] ...]

18:53 Then I was just going to (partial mapv vector coll) that sucker.

18:53 DerGuteMoritz: ok that was fun, but now good night :-)

18:53 sdegutis: Dangit. I think DerGuteMoritz just did it again.

18:57 Aha! I knew it had something to do with repeatedly or repeat or iterate!

18:57 And yet, I feel oddly dissatisfied for not coming up with it myself.

18:57 I'm sorry #clojure. I'm sorry I asked you to do my day job for me. I just.. I had no idea that you would also get the /satisfaction/ from doing it.

18:58 Well, at the very least, I got to clean it up and make it beautiful:

18:58 ,(let [coll [:a :b :c :d :e]] (->> coll (iterate pop) (take (count coll)) (reverse) (cons []) (mapv vector coll)))

18:58 clojurebot: [[:a []] [:b [:a]] [:c [:a :b]] [:d [:a :b :c]] [:e [:a :b :c :d]]]

18:59 michaniskin__: excellent

19:03 eblood: justin_smith: thanks.. that worked

19:28 slester: I'm struggling a bit with laying out my code; it seems bad to have to (declare) a bunch of functions at the beginning :(

19:28 gfredericks: TimMc: I missed your comments earlier

19:28 I do appreciate the "no two elements are unequal" formulation

19:29 but regarding your other one about removing elements, you have the flipside of "adding an element can always turn true to false", which wouldn't be true for (=)

19:29 slester: My code if someone is generous enough to given comments: https://github.com/slester/amiss/blob/master/src/amiss/core.clj -- always appreciated! I'll keep doing some searching to see what the Internet says

19:30 justin_smith: slester: I think the logic of your domain means that inherently each operation needs to conditionally invoke others

19:31 slester: you could use a big letfn or something, but it is cleaner to just declare them and let them mutually conditionally call one another

19:35 {blake}: Is there a "mapmerge" equivalent of "mapcat"?

19:36 justin_smith: {blake}: isn't that just (partial reduce merge) ?

19:36 oh no, you are doing some function to each element before merging

19:36 sdegutis: {blake}: How about (->> coll (map f) (apply merge))

19:36 justin_smith: so it's (apply merge (map f coll))

19:37 sdegutis: justin_smith: Oh reduce, clever.

19:37 I like how (partial) is implicit in Haskell and (comp) is just .

19:37 {blake}: justin_smith, sdegutis: Right. I was just looking at mapcat and it's (apply concat (apply map f colls))) so I figured there might be one for merge.

19:37 sdegutis: ,(source mapcat)

19:37 clojurebot: Source not found\n

19:38 sdegutis: Are you drunk clojurebot?

19:38 ##(source mapcat)

19:38 lazybot: java.lang.RuntimeException: Unable to resolve symbol: source in this context

19:38 sdegutis: Oh.

19:38 ,(clojure.repl/source mapcat)

19:38 clojurebot: Source not found\n

19:38 sdegutis: ##(clojure.repl/source mapcat)

19:38 lazybot: ⇒ Source not found nil

19:38 sdegutis: FINE, bots.

19:39 iamjarvo: is there a way for lein repl to load all the files in /src? ive been having to (load-file "file_path")

19:39 justin_smith: iamjarvo: you can specify :main in your project.clj

19:40 iamjarvo: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L196

19:41 amalloy: ~def mapcat

19:42 iamjarvo: justin_smith but thats one namespace, i guess the main namespace should require all the dependencies

19:45 i was sort of hoping to load the repl and require a namespace or use a namespace as needed

20:31 hefesto: How do you concatenate two strings?

20:32 something like: (+ "string 1" "string 2")

20:32 clojure.string doesnt seem to have a function that does it.

20:33 gfredericks: ,(str "string 1" "string 2")

20:33 clojurebot: "string 1string 2"

20:34 hefesto: thank you!

20:34 :)

21:10 TimMc: gfredericks: Interesting point about adding elements!

21:13 gfredericks: do any lisps evaluate (=)?

21:20 justin_smith: guile> (=) => #t

21:20 first one I tried

21:21 common lisps don't like it

21:33 gfredericks: I don't imagine the question even applies to any other popular languages

21:34 justin_smith: lush demands exactly two arguments

21:34 TimMc: =.apply([])

21:41 kclawl: what makes clojure more functional than python?

21:42 gfredericks: immutable data structures?

21:42 kclawl: anything else?

21:42 justin_smith: kclawl: the core functions and data structures make side effects rare

21:43 kclawl: in python you can code functionally if you have a lot of self discipline and keep track of the gotchas (hidden or unexpected mutation) - in clojure it's the default, the easy way to code

21:46 kclawl: yeah I see

22:18 TimMc: You can opt out of it, of course, but it has to be somewhat explicit.

22:20 gfredericks: it's not just a language attribute it's a community/ecosystem thing too

22:27 sg2002: kclawl: The semantics itself is more functional too. Python expressions are imperative.

22:36 kclawl: sg2002 hmm, what makes python expressions imperative?

22:43 gfredericks: do all python expressions return something?

22:47 sg2002: kclawl: Lisp expressions are functional because they always return a value. Python expressions generally don't return a value. if a==b{ x} else{ y} in an imperative language like python means "DO x when a==b or DO y". In a lisp similar statement means "return value from doing x when a==b or value from doing y".

22:52 kclawl: ah ok.. python is if expression too, but it is kind of ugly and backwards

22:52 10 if True else 20

22:59 sg2002: kclawl: Python expressions are not backwards or ugly, but from the point of functional programming those expressions are a layer of accidential complexity.

23:01 kclawl: 10 if True else 20 is backward and ugly

23:01 first a then value, then boolean check, then else

23:29 amalloy: gfredericks: i think expressions that don't return something get called statements

Logging service provided by n01se.net