#clojure log - Jan 08 2016

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

0:00 BRODUS: kovrik: not quite. i just dont expect there to be a difference in behavior if I evaluate code directly or indirectly

0:01 tolstoy: fingertoe: Convert the values to numbers? Or is that the prob?

0:04 BRODUS: prints fine im in the buffer and use "cider-eval-last-sexp", but if i call an elisp function that uses "cider-nrepl-sync-request:eval" on the same code then nothing prints

0:05 tolstoy: ,(apply + (map #(* -1 (read-string (subs % 1 (dec (count %))))) ["(12.50)" "(7.49)" "(8.12)"

0:05 "(9.99)" "(4.72)" "(5.98)" "(9.45)" "(25.79)" "(6.70)" "(22.43)" "(4.75)" "(4.69)"]))

0:05 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

0:05 fingertoe: The ( ) notation of negative needs stripped, then the converted to a - number. I have been able to get one at a time.. but not the whole thing..

0:05 tolstoy: ,(apply + (map #(* -1 (read-string (subs % 1 (dec (count %))))) ["(12.50)" "(7.49)" "(8.12)" "(9.99)" "(4.72)" "(5.98)" "(9.45)" "(25.79)" "(6.70)" "(22.43)" "(4.75)" "(4.69)"]))

0:05 clojurebot: -122.60999999999999

0:06 tolstoy: fingertoe: I don't know if that example is clear, but, you can use the "subs" function to get a substring.

0:07 fingertoe: Then use read-string to convert it to a number. Then multiply by -1. Then add it up (apply + [bunch of numbers]).

0:07 rhg135: Technically (1) is valid

0:08 TEttinger: ,(reduce #(- %1 (first (read-string %2))) 0 ["(12.50)" "(7.49)" "(8.12)" "(9.99)" "(4.72)" "(5.98)" "(9.45)" "(25.79)" "(6.70)" "(22.43)" "(4.75)" "(4.69)"])

0:08 clojurebot: -122.60999999999999

0:08 rhg135: It is a list of a number, just get the first and flip it

0:08 TEttinger: that's what I did too, rhg135!

0:09 rhg135: Ah, cool

0:09 tolstoy: Ah, yeah.

0:09 I suppose a string/replace would be fun, too.

0:10 rhg135: It would

0:12 fingertoe: Thanks! that should get me on my way. I am importing a spreadsheet from expensify, and summing stuff by category - I didn't have too much trouble with the positive amounts but the negative notation was too much to learn in one bite. ;-0

0:12 TEttinger: ,(apply - 0 (read-string (clojure.string/replace (apply str ["(12.50)" "(7.49)" "(8.12)" "(9.99)" "(4.72)" "(5.98)" "(9.45)" "(25.79)" "(6.70)" "(22.43)" "(4.75)" "(4.69)"]) #"\)\(" " ")))

0:12 clojurebot: -122.60999999999999

0:13 tolstoy: ,(read-string (with-out-str (print ["(12.50)" "(7.49)" "(8.12)" "(9.99)" "(4.72)" "(5.98)" "(9.45)" "(25.79)" "(6.70)" "(22.43)" "(4.75)" "(4.69)"])))

0:13 clojurebot: [(12.5) (7.49) (8.12) (9.99) (4.72) ...]

0:14 TEttinger: I wonder...

0:14 tolstoy: ,(reduce #(- %1 (first %2)) 0 (read-string (with-out-str (print ["(12.50)" "(7.49)" "(8.12)" "(9.99)" "(4.72)" "(5.98)" "(9.45)" "(25.79)" "(6.70)" "(22.43)" "(4.75)" "(4.69)"]))))

0:14 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Symbol"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Symbol"\n :at [clojure.lang.RT seqFrom "RT.java" 542]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 542]\n [clojure.lang.RT seq "RT.java" 523]\n [clojure.lang.RT first "RT.java" 668]\n [clojure.core$fi...

0:14 tolstoy: Huh. Worked in my repl.

0:15 Anyway, convert the whole list into a string in one pass. ;)

0:18 TEttinger: ,(apply + (map (comp - first read-string) ["(12.50)" "(7.49)" "(8.12)" "(9.99)" "(4.72)" "(5.98)" "(9.45)" "(25.79)" "(6.70)" "(22.43)" "(4.75)" "(4.69)"]))

0:18 clojurebot: -122.60999999999999

0:20 TEttinger: fingertoe: (comp - first read-string) is a way to construct a fn from those component parts, it turns "(12.50)" into -12.5 . you could use it on negative numbers with the parenthesized weird notation that expensify uses, but I'm not sure yet how to best switch around between reading positive and negative numbers

0:22 (comp #(if (seq %) (- (first %)) %) read-string)

0:23 ,(apply + (map (comp #(if (seq %) (- (first %)) %) read-string) ["(12.50)" "7.49" "8.12" "(9.99)" "(4.72)" "5.98" "0.45)" "125.79" "6.70" "(22.43)" "(4.75)" "(4.69)"]))

0:23 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Double"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Double"\n :at [clojure.lang.RT seqFrom "RT.java" 542]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 542]\n [clojure.lang.RT seq "RT.java" 523]\n [clojure.core$seq__4351 invokeStatic "core.clj" 137]\n [clojur...

0:23 TEttinger: ,(apply + (map (comp #(if (seq? %) (- (first %)) %) read-string) ["(12.50)" "7.49" "8.12" "(9.99)" "(4.72)" "5.98" "0.45)" "125.79" "6.70" "(22.43)" "(4.75)" "(4.69)"]))

0:23 clojurebot: 95.45000000000002

0:24 fingertoe: I have been doing (def totperdium (reduce + (map bigdec (mapv :Amount mealcharged)))) on to get the totals on all of the positive catagories. Probably not the tidiest but it worked.

0:24 The string thing is probably better?

0:24 TEttinger: not sure

0:24 there have been some good suggestions and some sorta "let's see how else we can do this" ones

0:25 like my string replacement one is not practical

0:26 fingertoe: Its all quite helpful to see -- I think that is the last crux -- Now that I can calculate that I can go back and look at better ways to do all my other catagories.

0:26 TEttinger: (comp bigdec #(if (seq? %) (- (first %)) %) read-string) ; this one should convert their negative and positive entries to the correct bigdec

0:27 ,(apply + (map (comp bigdec #(if (seq? %) (- (first %)) %) read-string) ["(12.50)" "7.49" "8.12" "(9.99)" "(4.72)" "5.98" "0.45)" "125.79" "6.70" "(22.43)" "(4.75)" "(4.69)"]))

0:27 clojurebot: 95.45M

0:27 TEttinger: clojure is absolutely awesome for data handling in my book.

0:27 I have used it to generate really complex text formatting things

0:28 analyze large spreadsheets of just tons of data

0:28 large spreadsheets for me are not large for other people, I know finance industry types live by excel

0:29 tolstoy: Seems like Excel is the modern Lisp Machine / Smalltalk Env. ;)

0:30 fingertoe: I hate expense reports. If I can write a little code to make them magically appear, that will make my life easier -- I will probably export my calcs back to an excel template - but the job will be pretty well done.

0:31 We do a lot of porportional billing over multiple clients so none of expensify's reporting stuff was adequate -- But Expensify is Darn nice for capturing everything..

0:31 tolstoy: Can you just type the line items into a file of EDN statements, then slurp them in to produce a report, and a csv file?

0:31 Oh, I see.

0:31 fingertoe: Plus learning Clojure is a big bonus. My REPL is begining to replace my calculator..

0:32 rplaca: fingertoe: if you want to create excel files from clojure, you can check out my excel-templates library

0:33 basically injects data into an excel spreadsheet so you can do the formatting in excel and the data manip in Clojure

0:34 fingertoe: I saw this talk before I started -- https://www.youtube.com/watch?v=qnJs79W0BDo is that the one?

0:34 rplaca: yup

0:34 that's me! :)

0:34 fingertoe: Good deal --- I plan on it!

0:35 Nice to meet you!

0:35 rplaca: likewise

0:36 fingertoe: My first warm up project was a chess960 position generator.. I like that project for a quick "getting your toes wet"

0:38 (Randomly place the chess pieces in the row with bishops on opposite colors and the King always between the rooks)

0:44 TEttinger: fingertoe, yeah I spend a fair amount of time privmsging the clojure eval bot I run to generate calculations when I don't feel like starting up a local repl

0:45 http://i.imgur.com/Bw3JtHT.png

0:46 BRODUS: what is that font?

0:46 TEttinger: unifont

0:47 it supports all of unicode, which is the main reason I use it

0:47 well, BMP

0:47 if I am choosing a font for "nice looking monospace", I usually use envy code r or inconsolata lgc (a custom variant)

0:48 fingertoe: I installed the REPL on my iPhone just to annoy my friends and co-workers.. It is handy though.

1:46 amandabb: whats a good way to edit multiple indicies of a 2d array at once?

1:46 something like this but that works: (assoc-in array2d [0 0] "a" [0 1] "b")

1:48 justin_smith: ,(reduce (fn [a [e coords]] (assoc-in a coords e)) [[][][]] [[[0 0] "a"] [[0 1] "b"]])

1:49 clojurebot: #error {\n :cause "Key must be integer"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Key must be integer"\n :at [clojure.lang.APersistentVector assoc "APersistentVector.java" 345]}]\n :trace\n [[clojure.lang.APersistentVector assoc "APersistentVector.java" 345]\n [clojure.lang.APersistentVector assoc "APersistentVector.java" 18]\n [clojure.lang.RT assoc "RT.java" 792]\n [...

1:49 justin_smith: erp

1:49 ,(reduce (fn [a [coords e]] (assoc-in a coords e)) [[][][]] [[[0 0] "a"] [[0 1] "b"]])

1:49 clojurebot: [["a" "b"] [] []]

1:50 justin_smith: ,(reduce (partial apply assoc-in) [[][][]] [[[0 0] "a"] [[0 1] "b"]])

1:50 clojurebot: [["a" "b"] [] []]

1:50 justin_smith: yaya

1:52 opqdonut: I thought there was a function called "assocs-in" that does that

1:52 but turns out it was just in our codebase :P

1:52 justin_smith: opqdonut: nice!

1:52 amandabb: staring at it trying to understand.. almost got it i think

1:53 justin_smith: ,(defn assocs-in [m & args] (reduce (partial apply assoc-in) m (partition 2 args)))

1:53 clojurebot: #'sandbox/assocs-in

1:54 justin_smith: ,(assocs-in [[][][]] [0 0] 'a [2 0] 'b)

1:54 clojurebot: [[a] [] [b]]

1:54 justin_smith: sweet!

1:54 amandabb: maybe the assocs-in def helps the former one make sense?

1:54 amandabb: yeah it does thanks

1:55 justin_smith: opqdonut: that's great, I have so many -> chained assoc-in calls in my codebase that I can change into assocs-in

1:56 opqdonut: heh, good for you

1:57 justin_smith: opqdonut: for some reason I never thought of defining that function- makes so much sense

2:06 amalloy: justin_smith: it's kinda impossible to write efficiently, though, if you have multiple updates that share a prefix

2:07 instead useful has something called adjoin, which is more general but for two maps specializes to deep-merge, and that *can* be efficient

2:08 catern: argh

2:08 i'm back

2:08 or not

2:08 justin_smith: amalloy: cool

2:09 amalloy: incidentally, if you care about efficiency and have update paths that are known at compile time you can rewrite those chained assoc-in things to use update-in at each place where two paths diverge

2:10 (-> m (assoc :x 1) (update-in [:y :z] assoc :a 1 :b 2))

2:11 instead of (assocs-in m [:x] 1 [:y :z :a] 1 [:y :z :b] 2)

2:11 justin_smith: yeah

2:11 then we get the "easy to read vs. easy to know exactly what's happening" thing

2:12 amalloy: aren't those exactly the same in this case? mine is clearly harder to read and also not so easy to understand what's happening, but it runs faster

2:12 i'm not proposing you have a macro do that rewrite for you, which i agree would be spooky magic

2:13 justin_smith: amalloy: with idiomatic indenting the second one is a lot clearer. Not a code clarity deal breaker of course, if the efficiency is an issue there.

2:14 amalloy: right

2:38 augustl: hmm, mori.hash(0) => 0, mori.hash(null) => 0

2:39 that can't be right :)

2:39 mori is the JS wrapper for the cljs data structures, btw

2:53 justin_smith: augustl: why can't it be right?

2:53 augustl: 0 and null isn't the same

2:54 justin_smith: augustl: all hashes have collisions

2:55 I mean, it might be a bad idea to have 0 and null collide for some reason? but collisions are inevitable

2:59 augustl: I expect that the value "0" comes from some predicates before running the actual hashing :)

3:00 I should probably use mori.equals instead of mori.hash(a) === mori.hash(b) though :)

3:00 mori.equals(0, null) returns false

3:17 amandabb: does filter guarantee order if done on a vector?

3:17 i need to remove some elements but everything else has to stay where it is

3:19 augustl: amandabb: yes

3:19 amandabb: hooray

3:19 thanks

3:19 augustl: amandabb: but you might not get a vector back

3:19 amandabb: ok ill call vec on it if i need to

3:19 BRODUS: or use filterv

3:19 amandabb: oh yeah i was going to ask about that

3:20 why are there v versions for a lot of functions?

3:20 BRODUS: because sometimes you need a vector

3:20 amandabb: seems messy

3:20 couldnt there be a v version for like.. most.. higher order functions?

3:20 i thought transducers or something were supposed to fix that but im not sure

3:55 engblom: souterrain: I saw someone has been downloading the gpio library from clojars.org. I am guessing it was you as you planned to do it. I am curious how it worked for you

5:44 domgetter: justin_smith: I went ahead and generalized the problem we were working on about conditional partitioning: https://gist.github.com/domgetter/3833a98997b58a2597f8

6:11 ridcully_: domgetter: you could use destructuring instead of the book/books arguments. [book & books] coll, later just pass books instead of (first books) (rest books)

6:13 domgetter: ridcully_: on line 5 or on line 6?

6:14 oh I think I understand

6:16 ridcully_: There, I changed it. Like that?

6:16 ridcully_: domgetter: yes

6:17 domgetter: awesome, thanks for the tip

6:18 TEttinger: ridcully_: I'm glad we have another helpful person here to advise on cleaning up code! thanks for being a substitute justin

6:24 wink: mhm, invalid ssl cert for clojure.org

6:24 but apparently nobody uses the https version

6:29 powered: why use https for static websites?

6:29 for man in the middle attacks or something?

6:31 mpenet: yep

6:32 it's not just a static website, it has links to binaries: http://clojure.org/downloads

6:32 could have malware injected in the page itself etc etc

6:35 augustl: the download link should be to https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0/clojure-1.7.0.zip instead of http://repo1.maven.org/maven2/org/clojure/clojure/1.7.0/clojure-1.7.0.zip

6:35 seems like clojure.org itself doesn't provide any downloads

6:35 mpenet: yes that too

6:35 the link is there, a mim you inject a link to whatever

6:35 could*

6:35 augustl: good point

6:36 mpenet: and mim attacks are more common than you think (hello "free wifi" acces in airports)

6:37 but yeah, targetting clojure.org for such things would be odd, but there are tons of vectors. in short https is good

6:38 ridcully_: TEttinger: that's like saying, paste is a substitute for butter ;)

6:38 wink: well, feel free to fire off a mail to any mailing list, I won't subscribe just for that :)

7:11 neurostorm: Hi.

7:11 I'm typing to update inside a tree-structure like this:

7:11 {:key nil,

7:11 :root

7:11 {:data {:key "123"},

7:11 :children

7:11 [{:data {:key "234"}, :children []}

7:11 {:data {:key "345", :x 12},

7:11 :children [{:data {:key "456"}, :children []}]}]}}

7:11 I can find the value i want to change, but loose ability to return the full modified tree. How can i change a value and return the full tree?

7:12 ,{:key nil, :root {:children [{:children [], :data {:key "234"}} {:children [{:children [], :data {:key "456"}}], :data {:key "345", :x 12}}],:data {:key "123"}}}

7:13 clojurebot: {:key nil, :root {:children [{:children [], :data {:key "234"}} {:children [{:children [], :data {:key "456"}}], :data {:key "345", :x 12}}], :data {:key "123"}}}

7:16 domgetter: ,(def neurosmap {:key nil, :root {:children [{:children [], :data {:key "234"}} {:children [{:children [], :data {:key "456"}}], :data {:key "345", :x 12}}],:data {:key "123"}}})

7:16 clojurebot: #'sandbox/neurosmap

7:16 domgetter: ,(update-in neurosmap [:root :children 0] conj 17)

7:16 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 542]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 542]\n [clojure.lang.RT seq "RT.java" 523]\n [clojure.lang.APersistentMap cons "APersistentMap.java" 40]\n [clo...

7:17 domgetter: ,(update-in neurosmap [:root :children 0 :children] conj 17)

7:17 clojurebot: {:key nil, :root {:children [{:children [17], :data {:key "234"}} {:children [{:children [], :data {:key "456"}}], :data {:key "345", :x 12}}], :data {:key "123"}}}

7:18 neurostorm: Thats it. Thanks.

7:21 Now i just need to write a find-path-to-key function :-)

7:55 domgetter: neurostorm is gone, but I think this is what they needed: https://gist.github.com/domgetter/138b14ac558b4aa52d18

7:57 justin_smith: domgetter: (fn [i e] [i e]) is vector

7:58 well, it's the version of vector that only takes two args I guess

7:58 domgetter: I needed the index of the child so I could build the path

7:58 justin_smith: domgetter: right

7:59 but you can replace "(fn [i e] [i e])" in that code with "vector"

7:59 or "list"

7:59 domgetter: ah I see what you mean

7:59 as if I did (fn [a] a) instead of identity

7:59 justin_smith: right

8:00 domgetter: is (map-indexed vector ...) a common idiom?

8:00 justin_smith: yes, but I usually use (map-indexed list ...) if all I am doing is destructuring it immediately and I don't need it to be a vector

8:01 domgetter: and it's exactly for this case, where you want to know the index of each item in a for

8:01 domgetter: sweet, I updated the gist

8:03 is the for loop preventing the recursive call from being in the tail position?

8:03 since the original function needs to work on the other children?

8:05 justin_smith: you could use keep rather than (filter identity (for ...)) ... (first (keep (fn [index child] (find-with-key ...)) (range) (:children ds)))

8:05 I don't know if that's an improvement or not

8:06 wait, is keep var-args...

8:06 ,(doc keep)

8:06 clojurebot: "([f] [f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects. Returns a transducer when no collection is provided."

8:06 justin_smith: never mind, keep is not var-args, so leave as is

8:08 domgetter: (defn convert-to-var-args [f] (partial apply f))

8:09 justin_smith: still wouldn't do the right thing - this one needs (comp (partial keep f) (partial apply map list)) I think

8:10 (partial apply map list) is a hell of a function btw

8:10 ,((partial apply map list) [[1 2] [3 4] [5 6]])

8:10 clojurebot: ((1 3 5) (2 4 6))

8:10 domgetter: I'm trying to understand what it would be. I'll go play with it

8:11 justin_smith: it's matrix-rotate or something

8:11 ridcully_: transpose?

8:11 clojurebot: (def transpose (partial apply map vector))

8:11 domgetter: nth-of-each ?

8:11 justin_smith: ridcully_: that's the word!

8:12 clojurebot: vector/list potato/potato

8:12 clojurebot: Cool story bro.

8:13 domgetter: why does vector have 5 arities?

8:14 performance?

8:14 clojurebot: performance is http://meshy.org/2009/12/13/widefinder-2-with-clojure.html

8:14 justin_smith: domgetter: yes, performance

8:14 clojurebot: you are super helpful this morning

8:14 clojurebot: Huh?

8:39 jsabeaudry: A little core.async puzzle: why is :done printed only if line 7 is commented out? https://www.refheap.com/113449

8:41 MJB47: im going to guess its something to do with buffering

8:41 can you define ch to be (chan 2)

8:41 ?

8:42 jsabeaudry: MJB47, yes but it defeats the purpose

8:43 domgetter: MJB47: that doesnt seem like it would matter. the second go block takes from the channel and then takes from a timeout. closing the channel results in the print if there's no timeout

8:44 MJB47: then i have no idea :(

8:47 domgetter: Is that how you take from a timeout?

8:47 justin_smith: MJB47: puts to closed channels returns immediatly

8:48 MJB47: or, I mean >! to closed channels returns immediately

8:48 jsabeaudry: domgetter, yes

8:49 domgetter: justin_smith: so if the timeout amount was sufficiently small, we'd see the same behavior?

8:50 justin_smith: domgetter: I'm experimenting now, but I believe so

8:50 jsabeaudry: domgetter, timeout of 1 yields the same result

8:53 justin_smith: domgetter: yes, with a short enough timeout I don't see :done

8:54 err, even with a short timeout of 1

8:54 when I make it a (chan 2), I see :done

8:57 actually, even (chan 1) is enough to make :done still come up with the timeout

8:58 MJB47: oh the arg is the size of the buffer

8:58 not "how many things can the channel hold at a time"

8:59 jsabeaudry: MJB47, those two things are the same?

8:59 justin_smith: right, (chan) is (chan 0)

8:59 MJB47: ^

8:59 justin_smith: jsabeaudry: (chan 0) can hold one item - no buffer though

8:59 that's the difference

8:59 MJB47: the chan holds a value, and with (chan 1) it can hold ANOTHER value in the buffer

9:01 jsabeaudry: justin_smith, no, (chan) holds 0, you can test it with (let [ch (chan)] (go (>! ch 1) (println "never prints")))

9:01 justin_smith: jsabeaudry: oh, right

9:06 jsabeaudry: ready for a hint?

9:07 justin_smith: jsabeaudry: here's a version that makes it easier to experiment with https://gist.github.com/noisesmith/d2b488f3f99dfb6ec524

9:07 jsabeaudry: sure

9:09 jsabeaudry: justin_smith, hint: add a (println (<! ch)) after the close! call

9:09 justin_smith, what exactly is "buffer" ?

9:09 justin_smith: jsabeaudry: oh, I fucked that up, one moment, fixing

9:09 jsabeaudry: and why does it matter?

9:09 oh ok

9:10 justin_smith: classic refactor mistake with magic numbers :)

9:10 jsabeaudry: updated https://gist.github.com/noisesmith/d2b488f3f99dfb6ec524

9:11 mpenet: jsabeaudry: it does matter depending on your usage of chan, especially with regards to the rate of puts/takes and what to do if/when it's full

9:12 ex how to handle backpressure

9:12 also internally you can only have 1024 pending puts per channel

9:13 by pending I mean "puts in the wait queue until there's room in the buffer"

9:21 lokien: ridcully_: I've done it, it turned out to be pretty easy. thanks for help

9:23 jsabeaudry: justin_smith, here is an updated version keeping the spirit of the puzzle: https://gist.github.com/jsab/ff8f4689d48192ab8a6f

9:25 basically showing that the buffer size is not relevant to the puzzle

9:31 justin_smith: jsabeaudry: I wasn't rewriting the puzzle, I was writing a function that would show behaviors of things similar to the puzzle, as a way of seeing what was actually happening

9:32 classic experimentation - you change a parameter and see how the behavior is changed

9:33 jonathanj: what is the most readable way of writing "if X then (foo X) else X"?

9:33 justin_smith: (and X (foo X)) perhaps?

9:33 MJB47: (if x (foo x) x)

9:34 justin_smith: (some-> x foo)

9:34 if nil is what you are checking for, that is

9:34 MJB47: actually

9:34 jonathanj: actually, i guess my case is slightly different, it's actually: x = ...; if pred then (foo x) else x

9:34 MJB47: (or (foo x) x) ?

9:34 no that doesnt work

9:34 justin_smith: MJB47: that runs (foo x) even if x is nil

9:35 which by the original is not right

9:35 MJB47: yer i realised after

9:35 jonathanj: hrm, i did (cond-> x (pred) (foo x)) but maybe some-> is actually shorter for this particular case

9:35 actually, no i do need the test to be something other than just checking nil

9:36 it's just kind of weird to write a cond with a single condition

9:36 justin_smith: OK, so it's not just if X, it's if (pred? X)

9:36 jonathanj: justin_smith: sorry, i'm doing a horrible job of explaining myself

9:36 justin_smith: (and (pred? x) (foo x))

9:36 jonathanj: the predicate doesn't actually need X

9:36 justin_smith: oh, never mind then

9:37 (when cond (foo x))

9:37 jonathanj: what i'm doing is (cond-> (create-image ...) (pred-something) (process-image))

9:37 unfortunately when returns nil when not cond

9:37 i want the original value

9:37 justin_smith: so we are back to (if pred (foo x) x)

9:38 jonathanj: yeah, pretty much, except using x twice like that means assigning it

9:38 i guess i can just define it further up the let

9:38 justin_smith: ((if pred foo identity) x)

9:38 jonathanj: i think the if is clearer than cond->

9:38 justin_smith: haha

9:38 jsabeaudry: hahahhaha

9:38 jonathanj: haha

9:39 jsabeaudry: the lenght we go to avoid letting a variable

10:45 princeso: how to "inject" definitions into a namespace? this doesnt work (let [x 1](in-ns 'an-ns)(def y x)) <- it defines into actual ns.

11:36 jsabeaudry: princeso, look-up the `intern` function

11:38 gf3: Raynes: holla

11:41 schmir: princeso: https://github.com/zcaudate/vinyasa

11:42 princeso: you want inject: https://github.com/zcaudate/vinyasa#inject

11:59 jarjar_prime: <o/

12:00 sdegutis: +1

12:00 chawls: does anyone know of a library offering an implementation of min/max heaps? I've found a few blogs explaining how one would write one in Clojure, but I'd rather use an existing implementation rather than rolling my own

12:26 phaseNi: Hello, is there a way to put metadata on the symbol that defun creates directly, rather than wrapping it in with-meta?

12:27 justin_smith: phaseNi: (defn ^{:foo "some value"} bar [])

12:28 phaseNi: also, (defn ^:foo bar []) which is a shorthand for (defn ^{:foo true} bar [])

12:28 phaseNi: user=> (defn ^{:foo "some value"} bar [])

12:28 #'user/bar

12:28 user=> (meta bar)

12:28 nil

12:28 luma: you need (meta #'bar)

12:28 justin_smith: phaseNi: (meta #'bar)

12:28 phaseNi: hmmm

12:29 justin_smith: phaseNi: bar returns the function, the function does not get metadata, #'bar returns the var, the var does get metadata

12:30 phaseNi: yeah, thats not what I need

12:30 (def baz (with-meta bar {:baz 1}))

12:30 I'm trying to avoid that...

12:30 justin_smith: phaseNi: OK, so you want metadata on the value and not the var

12:31 phaseNi: yes

12:32 is it possible, without a defun like macro?

12:32 sdegutis: Bidi or Silk? YOU decide!

12:34 But seriously. Which one y'all prefer?

12:35 phaseNi: https://carouselapps.com/2015/09/21/bidi-vs-silk/

12:35 you've seen that?

12:36 wink: yuck

12:37 that sounds horribl

12:37 momerath42: I've read the java interop page, and maybe it's just my lack of java knowledge, but I can't figure out how to: call a method that a java object I have in hand is supposed to have inherited from a parent class

12:37 wink: I mean.. disencouraging that is all fine, but outright disable that feature...

12:38 momerath42: I'd be surprised if it didn't work just like calling a method defined in that child class...

12:38 momerath42: i get an IllegalArgumentException "no matching field found"

12:39 i'm guessing it's a namespace issue, but haven't figured out how to import the methods of the parent class (AbstractHistogram which Histogram inherits from; this is in the HdrHistogram lib)

12:40 wink: (.toString (java.sql.Time. 1234)) "01:00:01"

12:40 I think your problem must be a different one

12:41 if class B extends A (in java) then you should not need to import anything besides B

12:42 momerath42: (.getTotalCount (Histogram. 1000 0))

12:42 0 (.getHistogramData (Histogram. 1000 0))

12:42 IllegalArgumentException No matching field found: getHistogramData for class org.HdrHistogram.Histogram

12:42 getTotalCount is defined in the child class, whereas getHistogramData is in AbstractHistogram

12:43 wink: it's not

12:43 https://github.com/HdrHistogram/HdrHistogram/blob/master/src/main/java/org/HdrHistogram/AbstractHistogram.java

12:43 your docs must be wrong

12:43 it's also not in AbstractHistograms's parent. unless I fail at searching

12:44 momerath42: hrmm- yeah, i was looking at some web-based class browser; I guess it's old, but then so are the quickstart docs on the official github page

12:44 wink: or jumped to the c# part in the readme. https://github.com/HdrHistogram/HdrHistogram/search?utf8=%E2%9C%93&q=getHistogramData

12:45 java interop is not pretty, but it works for cases such as this ;)

12:45 (it is *awesome* - just not pretty, imho)

12:47 momerath42: the github readme doesn't say what language the example code is in, that I can see, but it looks like java to me; is it actually c#?

12:51 looks like the api changed significantly, but not the readme; just going by the test code now, and have what I need. thanks!

12:55 wink: good luck :)

12:55 I think there's both languages in the repo

12:57 sdegutis: does github.com/juxt go by another nick in here?

12:59 wink: it's an org.

13:01 sdegutis: Oh.

13:02 Why is it generally better to call a method via (method r) on a record, rather than (.method r) ?

13:07 jsabeaudry: Can a closure close on itself?

13:07 sdegutis: jsabeaudry: technically no

13:07 jsabeaudry: however, fn can be named

13:07 jsabeaudry: watch this

13:07 ,((fn x [] (x) ))

13:07 clojurebot: #error {\n :cause nil\n :via\n [{:type java.lang.StackOverflowError\n :message nil\n :at [sandbox$eval25$x__26 invoke "NO_SOURCE_FILE" -1]}]\n :trace\n [[sandbox$eval25$x__26 invoke "NO_SOURCE_FILE" -1]\n [sandbox$eval25$x__26 invoke "NO_SOURCE_FILE" 0]\n [sandbox$eval25$x__26 invoke "NO_SOURCE_FILE" 0]\n [sandbox$eval25$x__26 invoke "NO_SOURCE_FILE" 0]\n [sandbox$eval25$x__26 invoke "NO_S...

13:07 sdegutis: jsabeaudry: so technically yes

13:08 ...kinda

13:08 jsabeaudry: sdegutis, sweet! I think its going to work! I need it to remove itself from an atom when it is done

13:09 sdegutis: jsabeaudry: ah clever

13:09 jsabeaudry: perhaps too clever? :D

13:09 jsabeaudry: sdegutis, perhaps ;)

13:10 sdegutis: jsabeaudry: however, it may leak.. I have no idea, that's too meta for my tiny brain

13:14 jsabeaudry: sdegutis, bah it's just a reference loop, a very small one

13:14 sdegutis: +1

13:19 jsabeaudry: sdegutis, wow, it works, thanks a lot that really made my day!

13:19 sdegutis: jsabeaudry: hoorah!

13:44 dnolen: https://twitter.com/swannodette/status/685532192605343744

13:44 ClojureScript 1.7.228 released

14:15 sdegutis: dnolen: oh nice, parallel builds

14:19 justin_smith: sdegutis: https://gist.github.com/noisesmith/735429288e69c6126f9a

14:20 sdegutis: justin_smith: bwahahahahoho

14:22 that reminds me of how you can .write to *out* to enforce parallel logging

14:25 justin_smith: sdegutis: right, but unlike apply println it won't consider each character a separate printing task to interleave with all others

14:25 so it is much less amusing

14:25 sdegutis: thats what i mean tho

14:26 (defn safe-println [s] (.write *out* (str s "\n")))

14:28 justin_smith: sdegutis: updated https://gist.github.com/noisesmith/735429288e69c6126f9a

14:29 def safe-printer (comp println #(clojure.string/join \space %&)))

14:29 actually has the same behavior as println (except for the interleaving annoyance)

14:29 sdegutis: mazing-tastic

14:30 justin_smith: sdegutis: with your version it's now one arg, and you need to do the space joining by hand

14:58 TimMc: Today's sadness: -XX:-OmitStackTraceInFastThrow and it not always being in effect

14:59 If you fail to set that, HotSpot will sometimes decide to not fill in the stack trace for certain exceptions.

14:59 Bronsa: TimMc: yup :( bit me way too many times

15:04 novak`: I'm playing around with Luminus and have an question about it's project organization (though I doubt it's maybe related to Leiningen). How thinks around <app-name>.config works? I see there is <app-name>/env/prod/config.clj and <app-name>/env/dev/config.clj and I understand what it doues but question is how? Is it related to Leiningen?

15:05 justin_smith: TimMc: had a case recently with a rare heisenbug and we had that turned on, but aviso/pretty still hid the actual details that would let us track the trace down... worst part was we never decided to use aviso, it was present transitively

15:24 sdegutis: I thought Luminus was deprecated?

15:24 Or was that something else?

15:32 loophole: hi

15:36 given this function: (defn x [& {:keys [a] :or {a 1} :as xmap}] (print xmap)). what's the reason the default values given in :or are not represented in xmap?

15:37 sdegutis: loophole: the default values are only for the destructured symbols themselves; the :as form gives you the map itself as it was received

15:38 The end.

15:38 loophole: sdegutis: ok. I wrote a macro for my needs. was just curious :)

15:39 sdegutis: ok

15:56 novak`: sdegutis: No, Luminus is actively developed (since it is just a lein template utilizes standard set of Clojure web libraries related to web)

15:56 sdegutis: You maybe talk about Noir?

15:59 sdegutis: "...web libraries related to web..." :D brilliant construction of mine...

16:00 sdegutis: novak`: oh ok thx

16:37 devn: How do I check whether a symbol is bound locally?

16:38 ,(let [x 1] (bound? x))

16:38 clojurebot: #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.Var"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.Var"\n :at [clojure.core$bound_QMARK_$fn__5490 invoke "core.clj" 5306]}]\n :trace\n [[clojure.core$bound_QMARK_$fn__5490 invoke "core.clj" 5306]\n [clojure.core$every_QMARK_ invokeStatic "core.clj" 2571]\n [clojure.core$...

16:38 devn: Thinking of something like this...

16:38 devth: ,(resolve (symbol "nope"))

16:38 clojurebot: nil

16:38 devth: ,(resolve (symbol "into"))

16:38 clojurebot: #'clojure.core/into

16:38 devth: are you talking about dynamic vars?

16:38 justin_smith: devth: did the form compile? if so the symbol is bound

16:39 err, sorry, devn ^

16:39 devth: :-)

16:39 devn: justin_smith: heh, so pretend you want it to compile either way :D

16:39 justin_smith: devn: ruby's over there ... ->

16:39 :)

16:40 devn: hahahahahahahahaha

16:40 <3

16:43 justin_smith: devn: there's some implementation details you can hack at if you really want to know if something is in scope, but it's messy and no compatibility is guaranteed between clojure versions iirc

16:43 devn: the whole premise is something clojure's design tries to push you away from

16:45 kwladyka: What is important for employers to hire Clojure developer? In most of cases people reject me because of not enough experienced even without talking with me. I attached example of my code https://github.com/kwladyka/chess-challenge and what i know from others my code is very good. I don't have standard carrier, because before i cofounded 2 companies and i have a lot of business experience also. What should i do to be good in eyes of

16:45 employers? What is your experience about that?

16:46 How to became an expert Clojure which employers want to hire. But i am not talking about skills... i am talking about what employers want to see what is not the same.

16:48 devth: kwladyka: build stuff and show it to them

16:48 kwladyka: devth this example of code is not enough? What kind of stuff is enough?

16:49 devth: it looks good but one example doesn't show much depth

16:49 i like to see that people love to build stuff (in any lang/tech, really)

16:50 open source projects are a plus

16:50 kwladyka: devth and this is not easy... for example now in work i do some things but.... i can't talk about that, show nothing, even tell name of companies, because of huge penalty.

16:50 devth: yeah that's hard

16:50 most people do open source on the side because they love it

16:51 kwladyka: devth i don't have enough time to really care about some open source project :( I can create something to show my potential but what?

16:52 devth: ok but you'll need to figure out some way to communicate your abilities & what motivates you. showing your work is easiest and carries the most weight.

16:52 no one really has enough time...

16:52 kwladyka: i am working in 2 companies now, i really don't have enough time to do something more now

16:52 ok, maybe in this way:

16:52 in your opinion open source is necessary or it can just project to show skills?

16:53 devth: i'd say it's more a nice to have. not necessary

16:53 kwladyka: mmm but for sure i don't have enough time to create something what people will really use

16:53 devth: ok. so if you don't have open source you'll need to be able to talk about some projects you have worked on.

16:53 kwladyka: or i don't see some opportunity ?

16:54 devth: tech you used. challenges you faced and how you solved them. etc

16:54 ystael: kwladyka: what is the most important property of the positions you are looking for? that you be programming in Clojure?

16:54 kwladyka: devth yeah but employers reject me without even talking with me :)

16:54 devth not every-time but too often

16:55 ystael: because, for example, my company would like to hire a developer for a job where a substantial amount of the code will be in Clojure. but "Clojure" is very far from the most important qualification we're looking for.

16:56 kwladyka: ystael i love solve business problems, optimise, creating solutions etc. especially when i can use my business experience during coding.

16:57 devth: kwladyka: if possible ask why you were rejected then address that problem. also meticulously go over everything you're presenting to them. consistency, no typos. well-designed, well-written resume.

16:57 ystael: kwladyka: Are you finding that the fact you've been working primarily in Clojure is actually a problem?

16:58 devth: kwladyka: your chess readme looks good, as does the code. might want to add a license.

16:59 kwladyka: ystael Clojure is problem because in my country is a few companies working in Clojure. So only companies outside my country have sense.

16:59 ystael: kwladyka: Does that mean you're looking largely outside your country, or considering non-Clojure jobs, or both?

16:59 kwladyka: Purpose for my question now is what should i do to became Clojure expert in for example 1 year. But still not about skills... about employers.

17:00 devth: i don't really know what it means to be an expert :)

17:00 ridcully_: be an expert first, then sneek in clojure ;)

17:00 kwladyka: ystael Clojure outside my country, Relocation ore remotely.

17:01 devth: kwladyka: try applying to lots of jobs

17:01 kwladyka: devth i don't know too, but for employers it has to mean something good :)

17:01 devth: i don't think employers are the keepers of the definition

17:01 their definitions probably vary quite a bit

17:02 lots of jobs don't require you to be an expert though

17:02 kwladyka: devth just became a man who you want to hire :)

17:02 i am afraid the problem can be i co-founded 2 companies.

17:02 I mean.... employers can afraid that

17:02 i am not pure coder

17:03 maybe they afraid i will quit

17:03 ridcully_: if an employer would look up those companies, what would it find out about them?

17:03 devth: i saw your linkedin page - might want to emphasize your code skills there. say software engineer or developer (as long as that's accurate). "IT" itself doesn't mean much.

17:04 kwladyka: ridcully_ one was sold many years ago and the second what is e-store and this company is a leader in my country, now trying get into UK

17:05 krainaherbaty.pl and hotcup.co

17:08 devth yes now i have description for manager in head. Before i had Clojure Developer description :)

17:15 jonathanj: is there a function in the core library for determining whethe two values are within some delta of one another?

17:18 justin_smith: jonathanj: not that I know of, but there is ulp

17:18 ,(Math/ulp 2.0)

17:18 clojurebot: 4.440892098500626E-16

17:18 justin_smith: ,(Math/ulp 0.2)

17:18 clojurebot: 2.7755575615628914E-17

17:18 justin_smith: etc.

17:19 sdegutis: Welp.

17:19 princeso: jsabeaudry schmir Thank you. I was looking for something more basic. like this (defmacro at-ns-do [nms body](let [actual-ns *ns*] `(binding [*ns* (create-ns ~nms)]~body)))

17:20 justin_smith: sdegutis: whelps http://www.petproductnews.com/puppies.jpeg

17:21 princeso: that's not more basic than (intern (create-ns nms) s val)

17:21 jonathanj: justin_smith: i also found this: https://github.com/clojure/algo.generic/blob/master/src/main/clojure/clojure/algo/generic/math_functions.clj#L208

17:21 justin_smith: princeso: it doesn't even need to be a macro

17:22 sdegutis: justin_smith: haha oh you

17:23 justin_smith: ,(intern (create-ns 'foobarbaz) 'hello "world") ; princeso

17:23 clojurebot: #'foobarbaz/hello

17:23 justin_smith: ,foobarbaz/hello

17:23 clojurebot: "world"

17:23 justin_smith: princeso: that's what you want right?

17:25 princeso: justin_smith. i want to execute data like this (defn ^{:...} fun [x] (if (= 1 x) ...))

17:27 justin_smith: (intern (create-ns target) '^{:...} fun (fn [x] (if (= 1 x) ...))

17:28 princeso: justin_smith let me try that :)

17:32 justin_smith: princeso: in my own repl that puts the expected meta on

17:32 18WABQT5G: justin_smith is a clojure deity

17:32 :D

17:33 slester: whoops.

17:33 princeso: justin_smith. ah thanks i actually tried that way. But I depend on yet written definitions "(defn ...)". So maybe im obligated to macro (defmacro at-ns-do [nms & body]`(binding [*ns* (create-ns ~nms)] ~@body))

17:35 justin_smith: princeso: (fn ...) can do everything (defn ...) can

17:36 sdegutis: and then some!

17:42 princeso: justin_smith thanks man. What im doing is altering definitions from .clj files, for debugging purposes. Transforming (in this case) from (defn ..) to (fn ...) would be a useles task. Thanks friend for taking the time.

17:43 justin_smith: princeso: oh, in that case just use robert.hooke

17:43 that's what it is for

17:43 or alter-var-root

17:43 robert.hooke is basically a more fancy way of replacing a function via alter-var-root

17:44 princeso: let me see that of robert :D you are a book man

17:44 justin_smith: also, if it's just for debugging, you could just use with-redefs

17:47 princeso: i dont know if implementing a lot of tools would be good when learning. Any way thanks for the recommendations

17:47 justin_smith

17:47 justin_smith: princeso: if you are just learning, you shouldn't be doing things by altering namespaces from the outside

17:48 princeso: but also, with-redefs is part of clojure.core, and very simple to use

17:49 princeso: justin_smithl let me put an eye on it.

17:50 rhg135: ,(doc with-redefs)

17:51 clojurebot: "([bindings & body]); binding => var-symbol temp-value-expr Temporarily redefines Vars while executing the body. The temp-value-exprs will be evaluated and each resulting value will replace in parallel the root value of its Var. After the body is executed, the root values of all the Vars will be set back to their old values. These temporary changes will be visible in all threads. Useful for mockin...

17:52 rhg135: justin_smith: except in ruby, where it's encouraged

17:58 my first assingment for a rails course had me monkeypatch the String class 0.o

17:58 turbofail: gross

17:59 rhg135: part of me died that day

17:59 justin_smith: princeso: in fact, it's also simple to do (load-file "my-copy.of-some-other-ns.clj") to load your alternat defs for exploration / debugging

17:59 and that might just be the easiest thing for your goal

18:08 amandabb: what's a good way of pausing a game or ending a game with core-async?

18:08 like, i have a lot of (go while true's) that sends commands to the game channel

18:08 should i make an atom boolean for like "is-game-running", use close! on core-async, or something else?

18:09 princeso: justin_smith yes im taking the namespace, say some.ns and transforming it into something like some.ns-2a5regi1845. The thing im doing is wrapping objects into an observer.. say you have (an-func ...) then you get (eye (an-func ...))

18:09 justin_smith: amandabb: you could have a pub/sub "tick" channel, and always wait for a tick before the next "round" of operations

18:10 princeso: yeah, I'd just use load-file to make clojure load the edited file

18:11 amandabb: yeah but then how would i stop the tick channel

18:11 jonathanj: don't publish to it, i guess?

18:11 princeso: justin_smith: i dont know , im loading every definition whit clojure.repl/source-fn, from that i walk the structure.

18:12 justin_smith: princeso: every jar contains the cljs files

18:12 princeso: a jar is a zip file

18:12 unzip it, edit the file, then use load-file to load the new definition

18:12 in fact, an editor like emacs or cursive will even do all that for you with a few keystrokes

18:13 the jars get downloaded by leiningen into your ~/.m2/repository directory

18:15 princeso: that sounds interesting. The way im doing it is metaing the things i want to watch like this (defn ^{:log {:dev {:eval ['call1 'call2 ...]}}}..

19:41 amandabb: is it possible to do a non-blocking take from a core async channel?

19:42 i want to have a go-loop that runs and does a bunch of putting and taking from channels but if a value ever comes in from a certain channel i want to stop the loop

19:44 something like this: (go-loop [running? true] ...wait... ...put on chan1... if chan2 has a value in it, exit loop, otherwise, recur)

19:45 amalloy: use alts with a timeout channel

19:45 amandabb: should the timeout just be like 1 millisecond?

19:47 celwell: Why does Hickey's Java code use weird indentation?: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LazySeq.java#L37

19:48 amandabb: celwell: looks like it's mixing tabs and spaces

19:50 amalloy: whatever timeout you want, amandabb

19:50 celwell: oh, i c. weird that's there's no space betwen ){ in function declaration either though.

19:50 amalloy: celwell: rich is a madman

19:50 amandabb: does rich still work on the language?

19:50 or has that mostly been passed on to others

19:51 TEttinger: I think he mostly works on datomic

19:51 but I'm guessing there

19:51 he makes occasional contributions on github

19:53 https://github.com/clojure/clojure/commits?author=richhickey

20:04 celwell: Trying to convert map with maps and/or lists as some values to more Java friendly objects. HashMap conversion works, but can't seem to get lists to convert to java.util.List.

20:04 (postwalk #(cond

20:04 (map? %) (java.util.HashMap. %)

20:04 (seq? %) (java.util.List. %)

20:04 :else %)

20:04 m)

20:05 ridcully_: List is an interface?

20:05 LinkedList maybe?

20:05 celwell: oh, i have to ArrayList or something?

20:06 that did it, thanks! (my java foo is not up to par)

20:22 slester: why is t (clojure.string/split s re) but (clojure.string/join separator s)

20:22 trying to explain to a friend why clojure is awesome and he points to things like that

20:22 haha

20:28 amalloy: i always get the order of split wrong too

20:29 puredanger: I think the idea is that string ops are like collection ops and take the data first

20:29 I think join is not like that because it's handy to partial

20:31 ridcully_: amalloy: ... in every language

20:32 retrogradeorbit: i think of the split order as similar to an operation on an object

20:32 you wouldnt write ",".split("a,b,c")

20:32 string.split basically

20:33 and rewrite the join as

20:33 (clojure.string/join s coll)

20:33 and you have the same order

20:35 slester: Learning clojure at times Ive found myself first going... no no, this is wrong

20:35 and then thinking deeply about it and going, hang on a minute, no the way I've always done this is wrong

20:35 like contains? on a vector

20:36 at first you're like WTF? and then you're like OMG!

20:37 slester: well, it may be handy to partial, but when threading it's a bit rough

20:37 (-> "somestring" (clojure.string/split #"") (clojure.string/join "")) doesn't work :(

20:37 which kind of seems odd to me I guess

20:39 retrogradeorbit: I would say then thread-first is not for that situation. You could write a function or use #() to reverse the arg order. not pretty but works

20:39 amalloy: retrogradeorbit: no, just add a ->>

20:39 BRODUS: could derefing an atom ever return an error?

20:39 amalloy: (-> s (split re) (->> join sep))

20:39 er

20:39 (-> s (split re) (->> (join sep)))

20:39 retrogradeorbit: ,(-> "somestring" (clojure.string/split #"") #(clojure.string/join "" %))

20:39 clojurebot: #error {\n :cause "clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type java.lang.ClassCastException\n ...

20:40 celwell: if you stick with core and just (interpose) and (apply str), that should work too

20:40 retrogradeorbit: ,(-> "somesting" (split #"") (->> (join "")))

20:40 clojurebot: #error {\n :cause "Unable to resolve symbol: join in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: join in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: join in this co...

20:41 retrogradeorbit: ,(-> "somesting" (clojure.string/split #"") (->> (slojure.string/join "")))

20:41 clojurebot: #error {\n :cause "slojure.string"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "slojure.string"\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.n...

20:41 retrogradeorbit: ,(-> "somesting" (clojure.string/split #"") (->> (clojure.string/join "")))

20:41 clojurebot: "somesting"

20:41 retrogradeorbit: hhah. thats awesome

20:41 amalloy: pro tip! thanks.

20:41 slester: that's possibly worse than (clojure.string/join "" (clojure.string/split #"" "something"))

20:42 amalloy: depends on what you want to emphasize

20:42 slester: err

20:42 retrogradeorbit: yeah

20:42 slester: "something" #"" -_-

20:42 retrogradeorbit: maybe not in that string case, but the idea of switching to threadlast is sound

20:43 celwell: i believe the (-> x (->> ...)) only works one way, fti. not: (->> x (-> ...))

20:44 retrogradeorbit: yeah I guess so. ->> in the first example gets the input arg tfrom the threaded first val of ->

20:45 slester: interesting, though. maybe I don't mind the parens anymore, but it's an eyesore to him

20:45 hard to get someone over that perhaps! not sure how I did?

20:46 amalloy: practice

20:46 everything in life is just practice

20:46 things are unfamiliar until they're not

20:46 retrogradeorbit: Ive found some devs are very stubborn

20:47 celwell: with rainbow-parens it's a really helpful experience

20:47 retrogradeorbit: as in, I know someone who when they _get it_ then pretends they havent got it so they can just reject it so the prove your wrong

20:47 yeah and paredit

20:47 without paredit I wouldnt do it

20:48 ridcully_: slester: use paredit. once something just fixes everything you no longer care.

20:48 retrogradeorbit: thats a good point actually, is your friend using an editor with good paredit support?

20:48 slester: I use paredit :P

20:48 and rainbow-parens

20:48 not sure what he's using actually, but probably just an unsetup text editor

20:48 retrogradeorbit: yep

20:48 slester: like an IntelliJ without Cursive

20:49 or reading my code on hastebin

20:49 :P

20:49 retrogradeorbit: as you know, you have to experience it. then it clicks

20:49 ridcully_: some showmatch equivalent is really the minimum. but paredit made my stop caring

20:49 BRODUS: ,(println (atom "foo"))

20:49 clojurebot: #object[clojure.lang.Atom 0x10f80328 {:status :ready, :val foo}]\n

20:49 slester: I want to get parinfer up & running

20:49 BRODUS: Will status ever be non ready for an atom?

20:49 slester: also I've tried emacs so many times (spacemacs too) and I just can't leave vim

20:50 retrogradeorbit: I found that of core.async too. All the talks by hickey went woosh over my head, until I just tried it and worked with it a bit. Then it clicked.

20:50 the brackets/paredit are the same

20:50 slester: yeah

20:50 parinfer seems so nice, though. the vim port is slow and annoying though

20:51 retrogradeorbit: the state of editors and paredit is pretty bleak

20:51 its hard to tell someone 'just use emacs'

20:52 slester: I really hate non-evil emacs haha

20:52 and I can't figure out how to configure spacemacs to be like my vim so I kind of gave up

20:52 retrogradeorbit: I've seen a guy trying to learn clojure on sublime. And the paredit seems to be clunky. He had heaps of problems.

20:53 he tried lighttable. But didn't like its limitations. and he didnt want to use it for the other languages hes working on at the same time

20:53 slester: with mine, it randomly gets confused and won't let me add parens unless I scomment them out

20:53 retrogradeorbit: then he tried emacs. He gave it a good shot. as in weeks. Eventually he thre it in. Says he just didn't like all the wierd keycombos he had to learn.

20:54 now hes on vim. And he seems happy with it.

20:54 slester: yay!

20:54 I like vim's functionality but it seems like a pain to write plugins for it

20:54 BRODUS: learning emacs is always a nonstarter if you have work to do and an editor you already know

20:54 slester: plus I feel like I should use emacs because Richard Stallman gets mad at me if I don't. Also it's written in Lisp.

20:55 ridcully_: yeah. tried to fix some figwheel stuff that anoyed me. boy that viml is not my kind of language...

20:56 retrogradeorbit: I was lucky. I had adopted emacs before I even discovered clojure

20:56 a senior dev I used to work with pushed me to use it. it was good advice

20:58 slester: well, I had a professor push us to use vim

20:58 haha

20:58 so I invested my time learning and configuring a vimrc

20:59 seems to be a huge waste of time to go to emacs

20:59 yet I've still tried spacemacs :(

20:59 Mirry: Is there any advantage to use emacs over vim ? (clojure wise)

21:00 I've been a hardcore vim user since forever, so I don't think I'd be able to switch but hey who knows if it improves my workflow

21:00 slester: cider is easier

21:00 celwell: It took me two months of frustration before I was matching the proficiency I had in Netbeans in Emacs. I still feel like I am only at 5% speed of what I could be in Emacs, but definitely faster than Netbeans flow. Though, it takes time to customize and learn an editor too; probably outweighing perceived speed improvements.

21:48 tolstoy: Emacs. Come for the cider, stay for the org-mode, or erc, or magit....

22:22 neoncontrails: A clojure ibrary with java dependencies won't work in clojurescript, correct?

22:23 tolstoy: Right.

22:23 clj-time vs cljs-time, etc.

22:24 neoncontrails: Makes sense. Thanks :-)

Logging service provided by n01se.net