#clojure log - Jun 16 2014

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

0:03 mdeboard: ,(fn [s] (let [sep #"," foo (clojure.string/split s sep)] (if (= (str (last s)) (str sep)) true false)))

0:03 clojurebot: #<sandbox$eval73$fn__74 sandbox$eval73$fn__74@15c2817>

0:03 mdeboard: Whoops, well yeah that

0:03 ,((fn [s] (let [sep #"," foo (clojure.string/split s sep)]

0:03 (if (= (str (last s)) (str sep)) true false))) "a,b,c,d,")

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

0:04 mdeboard: ,((fn [s] (let [sep #"," foo (clojure.string/split s sep)] (if (= (str (last s)) (str sep)) true false))) "a,b,c,d,")

0:04 clojurebot: true

0:04 mdeboard: ,((fn [s] (let [sep #"," foo (clojure.string/split s sep)] (if (= (str (last s)) (str sep)) true false))) "a,b,c,d")

0:04 clojurebot: false

0:04 mdeboard: kelseygi: ^ ?

0:04 kelseygi: yeah, that’s where i was going—check the last char, treat the array differently in each one

0:05 i guess i was secretly hoping for something like a split-with on string with regex?

0:05 andyf: ,(clojure.string/split "a,b,c,d" #"," -1)

0:05 clojurebot: ["a" "b" "c" "d"]

0:05 andyf: ,(clojure.string/split "a,b,c,d," #"," -1)

0:05 clojurebot: ["a" "b" "c" "d" ""]

0:05 andyf: kelseygi: ^^^

0:06 mdeboard: noice

0:06 kelseygi: ooooh!

0:06 mdeboard: stil have to treat the array differently :P

0:06 kelseygi: i totally missed that in the clojuredocs example, thank you!

0:07 that works for this particular case, the thing i was going to do if it *doesn’t* end in the separator was store an empty string

0:08 dbasch: that should be in the doc string, because it’s not obvious behavior for the limit parameter

0:08 mdeboard: Now, what about comparing vectors? like how would I "diff" [1 1 3 5] and [1 1 2 3 4 5 5], such that it would return [2 4 5]

0:09 kelseygi: dbasch: much agreed

0:09 mdeboard: there are dupes so sets wouldn't work

0:10 andyf: dbasch: You can create a ticket requesting such a change. It may or may not be accepted. Not easy to tell until one tries.

0:10 doc strings tend to be terse

0:10 by choice

0:10 mdeboard: far too terse in many cases

0:11 dbasch: andyf: true, but they do try to document the expected behavior of a function with expected parameters

0:11 andyf: One can make their own doc strings that expand on the originals, e.g. https://github.com/jafingerhut/thalia

0:12 That project only scratches the surface, and I haven't added to it in a while, but if people are interested in longer doc strings and have the time to write them, send a pull request.

0:12 johnwalker: thanks for lein 2.4.2

0:12 dbasch: e.g.

0:12 ,(reduce 1 1 [])

0:12 clojurebot: 1

0:12 dbasch: ^^ that works according to the doc string of reduce

0:13 johnwalker: ,(reduce 'foobar 1 [])

0:13 clojurebot: 1

0:13 andyf: mdeboard: If you want to write 600 expanded doc strings, or even 10, go for it. I don't mean that sarcastically -- it only takes time.

0:13 johnwalker: hahaha

0:13 thats cute

0:14 mdeboard: andyf: I mean, it's not a philosophical point... many doc strings are close to useless as documentation, i.e. helping people understand what a function does.

0:14 andyf: one can complain, or one can do something useful about it

0:15 mdeboard: I mean, I literally can't do something useful about it because I don't know what the function does because their documentation doesn't explain it well

0:16 andyf: there is the source code, and docs on the Java API's

0:16 I am not demanding that you do something -- I am pointing out an alternative to complaining. That's all.

0:16 mdeboard: eyeroll

0:16 at the passive aggressiveness

0:17 andyf: There is no aggressiveness in my mind at all.

0:18 hellofunk: Anyone know how to route an abitrary URI like /whatever to show the contents of a specific HTML file? route/files seems to require the URI *is* the HTML file

0:18 Using Compojure, of course

0:18 johnwalker: did you see what hyPiRion did with deliver dbasch?

0:18 brehaut: hellofunk: just make a route and return that specific html file

0:19 files are a vald response :body

0:19 dbasch: johnwalker: no

0:19 hellofunk: brehaut: when you say "return" it, how exactly?

0:19 johnwalker: ,(map deliver [inc dec] [10 11])

0:19 clojurebot: (11 10)

0:20 hellofunk: brehaut: you mean [:body "something.html"] ?

0:20 umpa: ,(defmacro forever [& body]`(while true ~@body))

0:20 clojurebot: #'sandbox/forever

0:20 johnwalker: he also did a good one with with clojure.string/replace

0:20 brehaut: hellofunk: return {:body (clojure.java.io/file path-to-filename) ...}

0:21 hellofunk: you need to go learn about ring right away

0:21 hellofunk: https://github.com/ring-clojure/ring/

0:21 dbasch: johnwalker: that’s a bit unexpected :)

0:22 hellofunk: brehaut ah doing it at the ring layer, not the compojure layer

0:22 brehaut or rather the hiccup layer

0:22 brehaut: hellofunk: compojure is just a small layer on top of ring, you cant use compojure without also using ring

0:22 johnwalker: his replace was better, but it was something like this

0:22 ,(clojure.string/replace "$1000$5000" #"\d{4}" (fn [s] (apply str (reverse s))))

0:22 clojurebot: "$0001$0005"

0:23 johnwalker: well, he actually did a parseint and exchanged those for unicode characters

0:23 but the idea is that you can pass functions to clojure.string/replace when the second arg is a regex

0:23 it doesn't work for strings, which is slightly irregular

0:24 brehaut: hellofunk: hiccup is just an html rendering layer

0:31 hellofunk: whenever I change my compojure routes function, i notice I must stop the webserver, compile the entire source file, then start the server again (connecting localhost). does this seem right?

0:31 johnwalker: have you tried using a var

0:31 for your routes?

0:31 with #'

0:32 hellofunk: looks like it is a var: (jetty/run-jetty (wrap-app #'app) {:port port :join? false}

0:33 ah, perhaps because my #'app refers to a def that in turn then refers to my routes, since #' is wrapping the routes inside cemerick's friend

0:34 johnwalker: i don't actually know if thats related

0:34 seems like it should work

0:35 hellofunk: johnwalker: good catch. I had one reference as a var, but what it referred to then did not reference my routes as var. changed that, workign nicely.

0:35 the Friend example doesn't use vars so I hadn't either.

0:35 johnwalker: oh, gotcha

0:35 glad i could help

0:39 hellofunk: johnwalker so am i!

0:40 johnwalker: :)

0:57 hellofunk: do i understand correctly that clojure.java.io/resource will look directly and implicitly in the leinengen resources/ directory?

1:00 amalloy: today's reminder of little-used clojure features: an alternate to the standard single-line comment character ";" is available in #!, in case you hate semicolons

1:01 hellofunk: amalloy curious are ; and #! both reader-level comment symbols?

1:01 amalloy: yes

1:01 hellofunk: it seems completely bizarre and pointless - who would use #! instead of a semicolon? but then you remember that that's a shebang

1:01 hellofunk: as opposed to (comment ...) which is actually compiled

1:01 a shemale, what?

1:01 in clojure??

1:02 lazybot: hellofunk: Uh, no. Why would you even ask?

1:02 hellofunk: oh, misread...

1:02 amalloy: good answer, lazybot

1:02 as always

1:02 hellofunk: indeed that was impressive. what triggered that response? the double question mark?

1:03 questions ending in clojure??

1:03 guess not

1:03 lazybot: hellofunk: Uh, no. Why would you even ask?

1:03 hellofunk: lazybot likes shemales?

1:03 guess not

1:03 you like this, what?

1:05 TEttinger: ??

1:05 lazybot: TEttinger: What are you, crazy? Of course not!

1:05 clojurebot: ? is suddenly

1:05 ecfuser59999: Does anyone know if the limit of 4 primitive arguments will be removed ?

1:06 amalloy: i wouldn't bet on it, ecfuser59999

1:06 it's pretty rare to need more than four distinct primitive args, and if you really do you can shove them into an array

1:07 ecfuser59999: I do math modelling and could easily use 10 or primitive arguments. Yes I could use an array but not a very nice way to pass parameters!

1:09 thanks anyways

1:25 mdeboard: How would I "diff" [1 1 3 5] and [1 1 2 3 4 5 5], such that it would return [2 4 5]

1:25 i feel like i'm missing something

1:39 amalloy: mdeboard: well, diff is a vaguely-defined problem. if it's guaranteed that all elements of the first list are present in the second, in the same order (or if those are the only answers you care about), then it's not too hard

1:40 mdeboard: amalloy: I think I got a solution with `frequencies`

1:40 amalloy: that's fine too, if you don't care about order

1:42 if you wanted to diff them in order, by which i basically mean "which elements from b would you have to remove in order to get a", you can do something like https://www.refheap.com/86669

1:43 behavior is undefined if there's no way to remove elements from b and wind up with a

1:53 mdeboard: ^

2:00 mdeboard: amalloy: interesting, thanks

2:14 I mean the "funny" part of this purely functional approach is that I'm managing exactly as much state as I was before

2:27 hellofunk: mdeboard you are using atoms, refs a lot?

2:38 ayia: Hi guys. I need a collection in clojure with specific rule for adding new elements. What is the best way to do this in clojure? I tried to ask google, but did not find much... It was even hard to build a proper query because I don't know the correct direction to go...

2:38 hellofunk: ayia what kind of rule?

2:40 pyrtsa: amalloy: Diff in general is a vaguely-defined problem but what mdeboard seemed to be talking about and what you came up with a good answer for in https://www.refheap.com/86669 is the well-defined problem of difference of sorted sequences, or essentially, bags.

2:40 ayia: hellofunk: My collection should be (most a probably a set) a collection of "path" vectors like [1 0 0 0], [1 0 1 0]... The rule should be: the new vector is "ok" to be conj-ed if it has at least one "peek/node/element" with bigger number at correspondent location... hm... hard to explain... will think more now:)

2:43 E.g. if I have [[1 0 2 0][2 0 1 0]] then I can't conj-ed [1 0 1 0], because no one from its peeks is "higher" than any other peek in correspondent place at available "paths"

2:44 OK paths are: [3 0 1 0], [1 0 3 0], [1 1 2 0], [2 0 1 1], [2 1 1 0], etc...

2:47 mdeboard: i'm doing this wrong, right? https://github.com/mattdeboard/ticket-to-ride/blob/functional-refactor/src/ttr/board.clj#L326-L347 All the swap! calls seems weird as hell to me

2:49 I guess I'm just not thinking with recursion hard enough

3:04 amalloy: yes, mdeboard, that's madness. all those swap! calls are just describing one pure function that acts on state, composed of five shorter ones

3:05 (swap! state (fn [state] (-> state (update-in [:players pname :routes :claimed] concat route) ...)))

3:07 really all of claim! can probably be a single swap! call, which takes in an old state and returns a new state

3:07 once you've done that, it becomes clear that you can drop the swap! and the atom from claim! entirely, and just call the function claim instead. then you can write (swap! state claim pname route)

3:08 does that make sense, mdeboard?

3:29 dhkl: When creating a map using the map literal {} in 1.6.0, (class {:a 1 :b 2}) says that it is a PersistentArrayMap, but when evaluating the form {:a 1 :b 2}, the insertion order is not perserved like an array-map should. What causes the inconsistency?

3:36 amalloy: map ordering should be regarded as entirely coincidental, unless you are specifically using a sorted-map

3:48 dhkl: Thanks amalloy

4:31 yocapybara: wonder if anyone can help a noob - I've got a sequence (2 4 6 8), and I've got a sequence of maps ( {a: 1} {a: 5 b: 2} {a: 4} {a: 5}) - I'm trying to get a sequence of maps but with items from that sequence in it as values, like ( {a: 1 new:2} {a: 5 b: 2 new: 4} {a: 4 new: 6} {a: 5 new: 8} ). I've been thinking of something like mapping assoc-in over the sequence of maps but my brain isn't working.

4:35 amalloy: yocapybara: you want to map a function over the two sequences at once: (map (fn [a b] (assoc b :new a)) as bs)

4:36 ddellacosta: ,(map #(assoc %1 :new %2) '({:a 1} {:a 5} {:a 4} {:a 5}) '(2 4 6 8))

4:36 clojurebot: eval service is offline

4:36 ddellacosta: d'oh

4:36 yocapybara: anyways, that's basically the same as what amalloy just said ^

4:37 amalloy: ddellacosta: lazybot's eval service is never offline, for what it's worth. as long as lazybot himself isn't offline, anyway

4:37 ddellacosta: amalloy: oh, didn't realize that, thanks

4:37 &(map #(assoc %1 :new %2) '({:a 1} {:a 5} {:a 4} {:a 5}) '(2 4 6 8))

4:37 lazybot: ⇒ ({:new 2, :a 1} {:new 4, :a 5} {:new 6, :a 4} {:new 8, :a 5})

4:37 yocapybara: amalloy, ddellacosta: thanks guys - that's where I started off but I couldn't quite figure it out. Hopefully it'll get easier as I get more used to thinking in clojure

4:38 ddellacosta: yocapybara: np, speaking from experience it does seem to. :-)

4:39 yocapybara: ddellacosta: :)

4:41 ayia: I have added my question at https://stackoverflow.com/questions/24239606/how-to-validate-filter-new-elements-to-be-conj-added-to-collection-in-clojure. I will appreciate any help... Thanks...

4:45 clgv: ayia: if [1 0 1 0] and [0 0 1 0] was acceptable, you are looking for incomparable/non-dominating in the sense of pareto-optimality

4:46 ayia: btw why is [2 0 1 1] [2 1 1 0] valid when the above example is not?

4:46 ddellacosta: ayia: here's one solution I think

4:46 &(defn add-peak [peak peaks] (if (>= (reduce + peak) (reduce + (first peaks))) (conj peaks peak) peaks))

4:46 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

4:47 clgv: ayia: or is insertion order important? such that [0 0 1 0], [1 0 1 0] would be valid

4:47 ddellacosta: &(add-peak [1 0 1 0] #{[1 0 2 0][2 0 1 0]})

4:47 lazybot: java.lang.RuntimeException: Unable to resolve symbol: add-peak in this context

4:47 ddellacosta: whoops

4:47 clgv: deevus: you want clojurebot since he allows `def`

4:47 ddellacosta: ayia: anyways, try that ^

4:47 clgv: clojurebot is offline now I believe

4:48 clgv: still? is he still rolling dice?

4:48 ddellacosta: ,(defn add-peak [peak peaks] (if (>= (reduce + peak) (reduce + (first peaks))) (conj peaks peak) peaks))

4:48 clojurebot: eval service is offline

4:48 ddellacosta: d'oh

4:49 ayia: my solution doesn't have particularly good efficiency but it works according to your constraints I believe

4:49 ayia: oh actually, I guess it's not bad

4:49 ayia: but it's not right...d'oh

4:50 * ddellacosta goes back to the drawing board

4:50 clgv: ddellacosta: did you understand clearly what he wants?

4:50 ayia: clgv: since we have #{[1 0 2 0][2 0 1 0]}, then [1 0 1 0] is not acceptable because its 0th element is not "higher" than 0th element of both already existed in a set...

4:50 ddellacosta: clgv: I thought I did

4:50 clgv: but I realized my solution was making the wrong assumption

4:51 clgv: ayia: to validate a single state strictly speaking a set would be wrong since you are interested in a time-order?

4:51 ayia: [2 0 1 1] is acceptable because its 3rd element is higher than 3rd element of both vectors in a set

4:51 clgv: ayia: how can that be ok? [1 0 3 0] [1 1 2 0]

4:51 ddellacosta: yeah, the only thing I'm coming up with is O(n^2) I think

4:51 clgv: it shrank on index 2

4:53 ayia: clgv: i did not mention "time"... because I though it was a separate problem. And solution for it, I know:) I think so at least:)

4:53 ddellacosta: ayia: so, would this work? (defn add-peak [peak peaks] (if (>= (reduce + peak) (apply max (map #(reduce + %) peaks))) (conj peaks peak) peaks))

4:54 that's assuming no ordering though

4:54 clgv: ayia: can you formulate mathmatically what a new vector must fulfill with respect to a vector of the set to be added?

4:54 ayia: actually my collection entries will be like: #{ {:peeks [1 0 2 0] :time 2000} {:peeks [2 0 1 0] :time 1000} }. And I want to sort it by :time

4:55 clgv: ayia: so peeks can vanish but somtimes they are not allowed to?

4:57 ayia: well if it some easy predicate that only one position must be bigger just use every?+some

4:58 ayia: hm... first of all... don't think much of this case like real emulation... The task I am solving is "mathematical"... It has no any sens about mountains:) I decided to use "mountains" terms just because it was easier for me to explain...

4:59 clgv: well if it is math better describe it with text+formulas next time ;)

4:59 ayia: So... My case... Is the case of some "virtual" mountains ridges... That can appear on the earth (let it be a sorted set) but only if they a "cooler" at least in something that any other ridge on earh

4:59 The "coolness" is the hight of at least some peak

5:00 clgv: sorry:) next time i will try with formulas... I have no formulas though....

5:01 I have only description:) in words:) but in terms of "vectors and their elements" not ridges...

5:03 ddellacosta: ayia: I'm not sure what your goals are with this; if you want a solution in clojure then I would use something like the function I posted above and sort the set after the fact.

5:03 clgv: ayia: yeah, if you want the one vector position must be higher you can just check that by using `every?` on the set and `some` on the positions to compare the given element with one of the set elements

5:14 ayia: clgv: yeah... that seems to be straightforward solution... I just thought may be there is any more "elegant" solution... In this task I can do like this... But if for example I will use often different implementations of "sets" with custom "element uniqueness definition"... Is there a way to implement this in clojure in a convenient way?

5:15 "like any way to add rule of uniqueness to the set"... like you add a custom "comparator" to the sorted-set

5:17 clgv: ayia: no your actually not changing the uniqueness property of the set. you just write a custom conj-like function that decides whether to add or not a given element

5:18 ayia: if you want something generic it would just boil down to (defn cond-conj [s pred x] (cond-> s pred (conj x)))

5:18 oops

5:18 ddellacosta: is it something I said

5:19 clgv: ayia: I meant it like that (defn cond-conj [s pred x] (cond-> s (pred s x) (conj x))) where pred is the "uniqueness" predicate in your words

5:20 ayia: clgv: I see... Good note! Thanks!

5:21 rurumate: what's a quick way to do a wget style download in clojure?

5:21 clgv: rurumate: `slurp` ?

5:21 rurumate: oh right, slurp takes an url I forgot thanks

5:22 clgv: rurumate: (slurp "http://www.google.de") ^^

5:22 rurumate: but that will load the thing to memory right? I want it written to a file

5:22 because it's 28 mb binary

5:22 clgv: so?

5:22 clojurebot: so is (add-to-list 'erc-keywords '("\\bso\\b" erc-default-face))

5:22 clgv: I'd have believed you if it was 5GB ;)

5:23 rurumate: no, we have not achieved that level of bloat yet. but we're working on it

5:23 clgv: rurumate: well the solution gets more complex when you require directly writing it to a file

5:24 you got to setup an inputstream for the URL and an outputstream for the file and there should by clojure.java.io/copy*

5:25 rurumate: oh, so I so (with-open [in (bla) out (bla)] (copy in out))?

5:26 why the starred version of copy though?

5:27 clgv: rurumate: didnt know if it was called copy-stream maybe ;)

5:27 rurumate: I'll try and post result when it's done

5:32 fenrock: clojure.java.io/copy "does not close any streams except those it opens itself (on a File)", which i take to meaning you only need the with-open if you're using streams, otherwise you should be able to do (io/copy (io/file src) (io/file dst)) and all streams will be closed for you, and it's buffered

5:32 rurumate: ok so the input will be a stream, but not the output

5:33 fenrock: but i think you mentioned a stream, so former will probably be right

5:33 yarp

5:56 rurumate: seems workey: https://www.refheap.com/86675

5:57 clgv: rurumate: looks good

5:57 rurumate:

5:57 rurumate: you probably can omit the `file` expression since it coercing anyway, a string or url would be coerced as well

5:58 rurumate: clgv: would anything but a file make sense here?

5:58 what if dest is url?

5:59 if we know it would fail, I think it's better to coerce explicitly

6:30 clgv: rurumate: well coercing url to a file wont change that it might file if it is not writable ;)

6:30 *fail

6:54 silasdavis: is there a nice way to

6:55 ,((juxt (partial map first) (partial map second)) [[1 2][3 4][5 6]])

6:55 clojurebot: [(1 3 5) (2 4 6)]

6:55 silasdavis: nicer*

6:56 philandstuff: ,(map vector [1 2] [3 4] [5 6])

6:56 clojurebot: ([1 3 5] [2 4 6])

6:56 bob2: darn, too slow

6:56 silasdavis: great

6:57 ,(apply map vector [[1 2][3 4][5 6]])

6:57 clojurebot: ([1 3 5] [2 4 6])

6:57 philandstuff: also works for more than two entries in the inputs

6:58 pyrtsa: ,(apply mapv vector [[1 2][3 4][5 6]]) ;; if you want to keep the structure

6:58 clojurebot: [[1 3 5] [2 4 6]]

6:58 silasdavis: yep, I forget map works that way

6:58 philandstuff: ,(map vector [1 2 3] [4 5 6] [7 8 9])

6:58 clojurebot: ([1 4 7] [2 5 8] [3 6 9])

6:58 silasdavis: pyrtsa, also handy

7:00 clgv: you can call that `transpose` ;)

7:00 pyrtsa: ,(def transpose (partial mapv vector))

7:00 clojurebot: #'sandbox/transpose

7:00 pyrtsa: ,(transpose [[1 2][3 4][5 6]])

7:00 clojurebot: [[[1 2]] [[3 4]] [[5 6]]]

7:01 pyrtsa: Duh.

7:01 clgv: apply ;)

7:01 pyrtsa: Yep.

7:01 clgv: ,(def transpose (partial apply mapv vector))

7:01 clojurebot: #'sandbox/transpose

7:01 pyrtsa: Thanks.

7:01 clgv: ,(transpose [[1 2][3 4][5 6]])

7:01 clojurebot: [[1 3 5] [2 4 6]]

7:02 silasdavis: ah very nice, that is how to think of it

7:08 clgv: transpose for list of maps is harder to do correctly ;)

7:14 silasdavis: clgv, not sure how you'd define that

7:15 using the keys as column/row indices

7:15 or treating the map as a sequence of k-v pairs?

7:15 clgv: silasdavis: list of map transposed to map of lists per key

7:15 silasdavis: ah

7:15 clgv: silasdavis: it is not exactly the same

7:15 agarman: that's more a pivot than a transpose

7:16 clgv: but also some kind of transpose and pretty handy for plotting or analyzing attributes ;)

7:16 silasdavis: comes up in exactly the same place though

7:16 if you're returning multiple values

7:16 clgv: agarman: I dont know that meaning of "pivot"

7:16 agarman: in Scalaz that is generalized to a function called sequence

7:17 clgv: pivot is a rotation of tabular data...

7:18 clgv: agarman: ah ok. might make sense then

7:18 agarman: clgv: not to be confused with a pivot as in quicksort

7:33 clgv: agarman: but transpose is the common principle, I'd say. consider that in the vector case the keywords are the positions ;)

7:43 agarman: clgv: anyhow, if you google with the term pivot, you get fairly relevant results like http://stackoverflow.com/questions/11438918/pivoting-data-via-clojure

7:44 clgv: agarman: yeah, I didnt want to deny that ;)

7:45 agarman: clgv: I'm happy to call it transpose or pivot or yarble, as long as folks know what I'm talking about :-)

7:45 clgv: though that example is doing something different than I meant

7:45 please not "yarble" ;)

7:47 agarman: clgv: is it that you have a List of Maps and want a Map of Lists...that's https://hackage.haskell.org/package/base-4.7.0.0/docs/Data-Traversable.html

7:47 :-)

7:49 clgv: yeah that was my initial description. it's getting more complex if you allow non-present keys in some of the maps ;)

7:49 agarman: ah, well good luck :-)

7:49 clgv: already done it some weeks ago ;)

8:06 Morgawr: is there a way to specify the size of the threadpool used by pmap?

8:07 clgv: no

8:07 Morgawr: if I were you I would not use pmap except for quick and dirty parallelization

8:08 we need a "pmap considered harmful" blog post

8:08 Morgawr: yeah I know, I'm just working on a study comparing various threading utilities/libraries (Among both java and clojure) and I'm now tackling pmap

8:08 I normally wouldn't use pmap :)

8:08 clgv: just note it as downside ;)

8:08 Morgawr: yeah

8:08 will do

8:09 clgv: it is using one of the threadpools eigther agent or future

8:09 ah no future^^

8:10 Morgawr: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6465

8:10 Morgawr: yeah, I'm looking at it now, thanks :)

8:10 clgv: but as far as I added you need to add +1 to that number

8:10 Morgawr: I was kind of hoping it would use the internal threadpool like agents do

8:10 clgv: so in principle it could have a param for that ^^

8:11 Morgawr: but instead it just does its own thing

8:11 yeah

8:11 clgv: it uses the one of futures so it does what you were hoping. but the limit is through the lazy construction there

8:12 Morgawr: clgv: I see

8:12 clgv: Morgawr: just recommend reducers over pmap

8:13 Morgawr: clgv: yeah, definitely

8:40 silasdavis: from time to time I keep restarting lighttable to get a fresh repl and make sure I'm not using any old definitions

8:40 can anyone suggest a good way of getting a fresh environment, either lighttable specific or not

8:40 agarman: fresh

8:41 and component

8:45 silasdavis: agarman, doesn't sound like it remove existing bindings

8:45 Glenjamin: silasdavis: i tend to just disconnect from repl, and then add a new connection

8:45 silasdavis: I'm also not sure how it would integrate with lighttable which seems to run an nrepl session per file

8:45 or per project

8:45 agarman: Glenjamin: everything is still in the namespace's if you just disconnect

8:46 Glenjamin: right, i mean i kill the repl session without quitting LT

8:47 i mostly use tools.namespace & a component-style setup, but you don't need to exit LT for a fresh session

8:47 agarman: silasdavis: I tend to leave my various project REPLs running until I reboot my dev box

8:47 _oggy: anybody using instaparse here? any idea how to specify a grammar for "character 'a' followed by exactly one other character (any other)"?

8:47 silasdavis: Glenjamin, what command do you use?

8:48 Glenjamin: silasdavis: "Editor: Disconnect clients attached to editor"

8:50 silasdavis: ah

8:50 ok so when you re-evaluate the namespace it will reconnect

8:50 I think that's pretty decent

8:52 agarman: (inc hyPiRion) ; just discovered cowsay thanks to lein-shell

8:52 lazybot: ⇒ 38

8:54 silasdavis: agarman, you might find this useful: https://github.com/erkin/ponysay in an enterprise setting

8:54 agarman: lol

9:03 (inc silasdavis)

9:03 lazybot: ⇒ 1

9:05 hyPiRion: agarman: haha

9:06 agarman: hyPiRion: silasdavis: these are the most amazing utility that I've brew installed this month!

9:42 stompyj: Have there been any good articles on clojure adoption recently?

9:56 johnnyblaze: When using a (map func col) is there a way to know that you are on the last item in the collection?

9:56 toast: not with map

9:56 maybe map-indexed?

9:57 johnnyblaze: K need to look at that haven't used it before. Thanks.

9:57 clgv: johnnyblaze: it's (map f (range) coll)

9:57 toast: It passes the index along with the item

9:58 drbobbeaty: stompyj: What are you looking for - specifically?

9:58 clgv: stompyj: 1 year ago counts?

9:59 stompyj: I don’t even need hard numbers, I’m just trying to convince people here in NYC that clojure is a viable language, and should be in the conversation as people are moving from ruby/python to go/scala

10:00 clgv: stompyj: so you are interested in numbers and not success stories?

10:01 drbobbeaty: stompyj: Well... I've been writing production clojure code for more than a year at Groupon. It's in use in several projects here, including real-time processing of our web and mobile event streams in Storm.

10:01 stompyj: numbers or recent success stories. there was a ton of momentum around core.async and cljs

10:01 clgv: stompyj: http://www.colinsteele.org/post/27929539434/60-000-growth-in-7-months-using-clojure-and-aws

10:01 stompyj: yeah, we’ve been writing clojure here @ indaba for a good 5 months now

10:01 and it’s been amazing

10:01 clgv: thanks!

10:02 and I know movable ink has a big clojure codebase now

10:02 justin_smith: stompyj: we used a lot of clojure when I worked with Instrument, a few of the sites running Caribou (our open source web framework we made for Instrument) are linked on the bottom of the official Caribou site http://let-caribou.in/

10:03 stompyj: How is Instrument? They seem pretty awesome

10:03 justin_smith: now that I mention it, there are more sites that should be added to that list

10:03 stompyj: very hip, very Portland

10:04 sadly, they've gotten big enough that the bigger clients they get now get to dictate the backend stack (or have a legacy backend they have to adapt), so they divested on Clojure (including Clojure devs like me)

10:05 I think they will find long term that was a poor choice, but it wasn't a bad layoff (they gave some severance etc.)

10:06 arrdem: justin_smith: sorry to hear that

10:06 _alejandro: stompyj: We're using it in NYC at Adaptly for a lot of our backend stack too

10:07 stompyj: we switched from mostly ruby; core.async has been great for us in production

10:07 stompyj: justin_smith: wow, that’s sad/ interesting

10:08 _alejandro: on the front-end? or back-end?

10:10 _alejandro: stompyj: back-end so far

10:10 stompyj: although I'm pushing for cljs :-)

10:11 stompyj: are you using core.async structures in the req/resp cycle?

10:11 or calling out to a persistent service

10:12 _alejandro: stompyj: both

10:15 Nikentic: Hey, I am looking for some learning resources. I've been doing some project euler but I don't really learn any "best practices" or such. Coming from a Python/C++ background.

10:15 Any books maybe? Online courses?

10:15 justin_smith: here's another Instrument site, with clj backend, cljs frontend http://onenorthpdx.com/

10:15 _alejandro: Nikentic: I like braveclojure and joy of clojure

10:15 arrdem: Nikentic: 4clojure comes well commended, but is like Project Euler in that it's just a bunch of exercises

10:15 _alejandro: Nikentic: in that order

10:16 stompyj: _alejandro: wow, I’d love to hear about the in-req-resp cycle stuff at some point

10:16 Nikentic: _alejandro: ok, thank you! arrdem, I'll check that one out!

10:18 _alejandro: stompyj: I'm not sure we're doing it the best way :-), but the request basically triggers a message to be put on a channel, and then the response waits for the output message from an output channel

10:18 stompyj: so there's basically a message 'processor' that is always running, and waiting for input messages

10:21 stompyj: definitely happy to answer specific questions too

10:22 Nikentic: _alejandro: have you got any open source project which source code is useful to read & learn?

10:24 _alejandro: Nikentic: Leinengen, Enlive, and Hiccup are all good, and seem to be recommended by others too

10:25 Nikentic: _alejandro: Leinengen & Enlive for sure. Been looking at some network based code too, pretty interesting

10:25 _alejandro: Nikentic: do you have any other recommendations? I should do more code reading

10:26 Nikentic: _alejandro: No, sorry. I started coding Clojure last week so haven't looked into much

10:26 stompyj: _alejandro: thanks.

10:26 Nikentic: The only code I've read into detail is https://github.com/Raynes/irclj

10:27 riemann is pretty cool too

10:43 mdallastella: caribou has just a couple of dependencies... :D

10:43 benzap: Was wondering, what does the carot simple mean?, like (def ^{:doc "something"} init? true)

10:43 _alejandro: benzap: it's used for metadata

10:44 benzap: http://clojure.org/reader (ctrl+f metadata)

10:44 benzap: _alejandro: ah thanks

10:47 I was more interested in the form of ^String x, and this seems to explain it

10:48 ddellacosta: benzap: that is type hinting

10:48 TimMc: ^String is ^{:tag String}

10:49 ddellacosta: benzap: more here on that specifically: http://clojure.org/java_interop#Java%20Interop-Type%20Hints

10:50 benzap: thank you, i'll give that a read

10:50 clgv: ,(.getCanonicalName (Class/forName "[D"))

10:50 clojurebot: "double[]"

10:56 mdallastella: anyway, caribou is quite impressive!

10:59 arohner: what is the best tool for configuring a server these days? pallet, or is there some new hotness?

10:59 mpenet: arohner: ansible is nice to work with

10:59 stompyj: arohner: I’ve been using ansible, to great success

10:59 with*

10:59 moved from chef

10:59 seubert: another + for ansible

11:00 _alejandro: stompyj: do you use ansible for deployment too? or just config mgmt?

11:00 apetresc: What's the advantage of ansible over chef?

11:00 seubert: apetresc: simplicity

11:00 stompyj: _alejandro: thats why I switched

11:00 apetresc: Ah, okay

11:00 But for someone who's already versed in chef, any compelling reason?

11:00 seubert: probably not

11:01 stompyj: apetresc: simplicity also, but writing a script that can both deploy, provision and create an instance was the deal sealer for me

11:01 wkelly: apetresc: ansible is better at orchestrating tasks across multiple servers (do something on server A, then B, then A)

11:01 stompyj: apetresc: if you want to be able to deploy

11:01 wkelly: but if you don't need to do that, then no

11:01 seubert: stompyj: why can't you do that with chef

11:01 (my chef is rusty at best, honest question)

11:01 stompyj: seubert: early versions of chef had a janky capistrano kind of thing built in, but it never worked, and it seems they’ve deprecated it

11:02 seubert: ah, gotcha

11:02 stompyj: seubert: I always had to do chef + capistrano

11:02 seubert: interesting, i don't recall ever running into that

11:02 i haven't touched chef in about a year though

11:02 wkelly: I think they are focusing on orchestration for the next release of chef

11:02 mpenet: ansible runs without agents too

11:02 stompyj: seubert: they’re changing it very rapidly, thats another reason why I switched. It broke too often

11:03 mpenet: like pallet too, unlike chef I think

11:03 stompyj: ansible is like a super thin layer over bash scripts

11:03 seubert: this is the biggest reason i never wanted to touch chef again: http://docs.opscode.com/essentials_cookbook_attribute_files.html#attribute-precedence

11:03 15 levels of precedence and good luck debugging that without stellar internal docs

11:03 (it's hell)

11:03 stompyj: yeah

11:04 the only thing I miss from chef are the detailed recipes, but that’s just a matter of time, until galaxy catches up

11:04 wkelly: no server infrastructure on ansible either, which is nice

11:05 stompyj: yeah, thats another big win

11:05 seubert: chef is faster than ansible if you're touching a lot of boxes since it isn't raw ssh

11:05 which is both good and bad

11:05 whaley: stompyj: galaxy?

11:05 seubert: whaley: https://galaxy.ansible.com/

11:06 basically sharing ansible playbooks

11:06 r4vi: doesn't ansible have a 0mq transport- you don'thave to ssh

11:06 stompyj: whaley: its their online repo of recipes. the goal being ansible-galaxy install clojure

11:06 whaley: *nod* thanks

11:06 stompyj: r4vi: it does. they’re ramping that up going forward

11:06 seubert: ooo i've never used the 0mq part of it

11:06 that sounds promising

11:06 wkelly: it does have a 0mq transport, but ansible breaks up work into tasks which execute in parallel on all of the nodes and then block until every node compeles the task

11:06 I do not think the transport is usually the bottleneck there

11:07 seubert: ah

11:07 my ignorance is showing

11:07 stompyj: wkelly: yeah, and another tip, this is a huge problem when trying to spin up multiple instances

11:07 its actually faster to spin up 1 instance in 4 different shells, then telling the ansible script to bring up 4 boxes at once

11:07 wkelly: hm!

11:08 we haven't seen that on rackspace

11:08 stompyj: wkelly: interesting. then maybe it’s just something goofy with ec2, but a single box comes up in 3-5 mins here, but all 4 took about 25-30

11:08 wkelly: (which, disclosure, is the company who I work for, so bias filter appropriately)

11:08 that is interesting

11:09 stompyj: ya, its because it was blocking at every step, for some reason

11:09 wkelly: we do a separate provisioning and configuration playbook

11:09 stompyj: to be fair. I didn’t dig into the whys, it may be something I’m (not) doing on my end

11:10 wkelly: this is really the only ansible I have messed with: https://github.com/ludditry/ansible-zwift

11:10 stompyj: yeah, we have a “build ec2 + provision + deploy” script, but then separate scripts for provision and deploying

11:10 wkelly: it spins stuff up on cloud servers for our testing but is generally meant to run on physical machines (deploying openstack swift)

11:10 stompyj: actually, its all the same scripts, we just use tagging to split things out

11:10 ahhh very cool

11:10 wkelly: yeah, that makes sense

11:11 but in any case, it seems to make networks in parallel, then spin the instances up in parallel, then make/attach block storage in parallel

11:12 which does mean that if for some reason one instance doesn't come up, the step fails, and configuration halts

11:13 not sure if the ec2 plugins work the same way

11:13 mdallastella: what about fabric?

11:13 stompyj: from what I understand, fabric is more like capistrano, just a deployment tool

11:14 wkelly: I haven't done much with fabric

11:14 mdallastella: stompyj: yeah, right

11:14 wkelly: I am a big fan of dsh or gnu parallel for distribution my sshes :)

11:15 er, distributing

11:15 stompyj: nice

11:36 Does anyone have any good reference / sites for tweaking the JVM for clojure production deployments?

11:48 erlis: hi guys, quick question. How can I preserve the type of the collection after some operations, for example "map". So if I have a vector I can keep a vector, same for set, hash...

11:48 any trick ?

11:48 Glenjamin: erlis: you can get a vector with mapv, but in general you'd need (into (empty coll) ...) i think

11:49 erlis: the point is that I don't know the type I have

11:49 (f coll) -> another_coll same time of coll

11:52 Glenjamin: yeah, (into (empty coll))

11:53 ,(doc empty)

11:53 clojurebot: "([coll]); Returns an empty collection of the same category as coll, or nil"

11:53 erlis: empty!!!

11:53 great! glenjamin

11:53 thanks!

11:53 those little functions that makes your life easier :)

11:54 arrdem: map-into should be a thing..

12:06 johnwalker: arrdem: ehh. in principle i guess, since there are a lot of other strange combinations

12:06 if-not when-not mapv mapcat some?

12:07 arrdem: johnwalker: I mean, not something I'd inflict on the core, but I agree that the core has some strange composed utility functions.

12:08 not that I object to the core packaging utility stuff, it's just that the core's in the halfway house of having some utility stuff, not wanting to take more and not having all of the utilities you'd want as amalloy's useful is proof.

12:08 johnwalker: agreed

12:14 kzar: Anyone use Linode here? Recommended? (Sorry very offtopic)

12:15 arrdem: there are a couple of people here who are Linode based and have had good things to say in the past

12:15 check the logs

12:16 zaphro: Getting an error with luminus new .... "Could not locate clojure/data/priority_map__init.class or clojure/data/priority_map.clj"

12:16 kzar: arrdem: Oh yea good idea thanks

12:16 arrdem: zaphro: either something has fsck'd dependencies or you forgot to add an explicit dependency.

12:17 zaphro: I haven't reached the deps stage yet. It won't install.

12:18 dbasch: zaphro: what’s the full command?

12:18 zaphro: lein new luminus proj1 +postgres +cljs +site

12:19 dbasch: zaphro: version of leiningen?

12:20 zaphro: (OS X Mountain Lion) Leiningen 2.4.0 on Java 1.8.0_05 Java HotSpot(TM) 64-Bit Server VM

12:20 Clojure 1.6.0

12:20 technomancy: zaphro: did you install via homebrew or a manual install?

12:21 toast: erlis, Glenjamin: I used fluokitten to do a map that maintains the collection type, but empty is probably better if it's all you need, since it's there in core

12:21 zaphro: Manual. I've even had luminus install fine before now, ie. before Lein 2.4.0

12:21 kzar: Is there a way to host multiple Clojure web apps on a server with only one instance of Java running, but that at the same time allows you to deploy new versions of each app separately?

12:22 fenrock: immutant is doing work in that area

12:22 kzar: (my VPS is quite RAM limited ATM)

12:22 technomancy: zaphro: very strange; I can't reproduce. can you try with an empty user profile?

12:23 Glenjamin: toast: ah, neat - there's also an fmap in algo.generic

12:23 kzar: fenrock: Is immutant any good?

12:23 zaphro: technomancy Not sure how I do that.

12:23 technomancy: zaphro: mv ~/.lein/profiles.clj ~

12:24 zaphro: technomancy Ah, yes. Will try.

12:24 toast: Glenjamin: yeah, that was it - fmap was the function; next time I'll reach for empty: great suggestion. I'll have a look at algo.generic, too

12:24 fenrock: kzar: only just started using it, 1.x version is JBoss 7 AS based, and i was easily able to deploy and undeploy separate apps. 2.x is alpha and allows you to deploy to non JBoss instances. it works, but i've not used it in anger. they have a channel they are very helpful on if you want to know more

12:25 arrdem: Glenjamin: I love that (fmap IFn IFn) is comp :P

12:25 kzar: Anyone want me to put in their Linode referral code? (Giving it a try)

12:25 fenrock: cool OK, good to know

12:28 zaphro: technomancy That worked.

12:28 :user

12:28 {:plugins

12:28 [[lein-ritz "0.7.0"]

12:28 [cider/cider-nrepl "0.7.0-SNAPSHOT"]

12:28 [lein-ancient "0.5.5"]

12:28 [lein-immutant "1.2.1"]

12:28 [org.bodil/lein-nashorn "0.1.2"]

12:28 [com.jakemccrary/lein-test-refresh "0.5.0"]]

12:28 :dependencies

12:28 [[org.clojure/clojure "1.6.0"]

12:28 [org.clojure/core.typed "0.2.52"]

12:28 [org.clojure/core.match "0.2.1"]

12:28 [nrepl-inspect "0.4.1"]

12:28 [org.clojure/tools.trace "0.7.8"]

12:28 TimMc: zaphro: D-:

12:29 Please use a pastebin in the future (such as refheap.com)

12:29 zaphro: Sorry. Slip of keyboard :)

12:30 arrdem: shift-insert is such a cruel mistress :P

12:30 zaphro: technomancy Wondering which one might be the culprit?

12:30 technomancy: zaphro: maybe try bisecting?

12:30 joegallo: your apology is not enough! prepare the brazen bull.

12:30 * arrdem rakes coals

12:35 ayia: this works &(sort-by (juxt :foo :bar) #{{:foo 2 :bar 11} {:bar 99 :foo 1} {:bar 55 :foo 2} {:foo 1 :bar 77}})

12:36 why does the following not work?

12:36 &(sort-by (juxt :foo :bar) > #{{:foo 2 :bar 11} {:bar 99 :foo 1} {:bar 55 :foo 2} {:foo 1 :bar 77}})

12:36 lazybot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

12:37 ayia: &(sort-by (juxt :foo :bar) #{{:foo 2 :bar 11} {:bar 99 :foo 1} {:bar 55 :foo 2} {:foo 1 :bar 77}})

12:37 lazybot: ⇒ ({:foo 1, :bar 77} {:foo 1, :bar 99} {:foo 2, :bar 11} {:foo 2, :bar 55})

12:37 rasmusto: ,(< [1 2] [3 4])

12:37 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>

12:38 rasmusto: ayia: hm, I guess the default comp fn isn't < or >

12:38 ayia: ah... I see... seems like in this case yes...

12:38 so I need to find proper comparator for me:)

12:39 rasmusto: ayia: ah, default is ##(compare [1 2] [3 4])

12:39 lazybot: ⇒ -1

12:41 rasmusto: &(sort #(compare %2 %1) [[1 2] [3 4]])

12:41 lazybot: ⇒ ([3 4] [1 2])

12:44 ayia: rasmusto: thanks! makes sense so far:)

12:45 gfredericks: Does anybody have any idea how this compojure defroutes expression works? https://github.com/JonyEpsilon/gorilla-repl/blob/develop/src/gorilla_repl/core.clj#L71

12:46 mdeboard: gfredericks: I'm sure someone does

12:46 gfredericks: But, seriously, what do you mean? Like how the defroutes macro works?

12:46 gfredericks: it looks like it just returns a ring handler instead of a response

12:46 mdeboard: in general

12:46 ayia: rasmuto: but seems like I will need my own comparator reimplemented... Because actually I need normal order for the first key, and reversed order for the second key...

12:47 gfredericks: mdeboard: no, I mean that specific usage that I linked to

12:47 Glenjamin: gfredericks: compile-route expands the body with ~@

12:47 hrm, that shouldn't make a difference

12:47 https://github.com/weavejester/compojure/blob/1.1.8/src/compojure/core.clj#L101

12:48 gfredericks: I'm not 100% sure this code works; haven't checked out the diff between the version I'm running and the master in this repo

12:48 looking into that now

12:49 Glenjamin: from how i follow this, i agree - there should be another function invocation to make this work

12:50 ,`(~@(fn [a] a))

12:50 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: sandbox$eval25$fn__26>

12:50 Glenjamin: ,(quote `(~@(fn [a] a)))

12:50 clojurebot: (clojure.core/seq (clojure.core/concat (fn [a] a)))

12:51 Glenjamin: ,(quote `(let [a b] ~@(fn [a] a))))

12:51 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/let)) (clojure.core/list (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/a)) (clojure.core/list (quote sandbox/b)))))) (fn [a] a)))

12:51 Glenjamin: oh wow

12:51 gfredericks: no I do think this code is working; I just can't figure out how on earth

12:52 mdeboard: that's not good

12:52 CookedGryphon: Does anyone know of a nice efficient immutable (I don't even want to conj) tuple2 thing I could use?

12:53 Glenjamin: CookedGryphon: clj-tuple has that i think

12:53 CookedGryphon: I was using clj-tuple which was great, but won't aot compile, or at least something is exploding in my release build

12:53 Glenjamin: oh, then i dunno

12:53 CookedGryphon: and yeah, even that does too much really

12:54 I don't care about doing any manipulations, as soon as it changes I'd want it to just become a straight forward persistentvector

12:54 I'm using a simple float[ but that doesn't serialise nicely

12:55 otherwise it works perfectly for my needs

12:55 Glenjamin: gfredericks: do you have a running repl for that project? would be good to see what it macroexpands to

13:03 gfredericks: this seems to work (do (defn func [req] {:status 418}) ((GET "/" [] func) {:request-method :get :uri "/"}))

13:04 aha, found it

13:04 there's a call to (render) on https://github.com/weavejester/compojure/blob/1.1.6/src/compojure/core.clj#L94

13:04 gfredericks: Glenjamin: I do

13:04 Glenjamin: https://github.com/weavejester/compojure/blob/1.1.8/src/compojure/response.clj#L30

13:05 compojure calls (render) on every route, and (render IFn) calls it with req

13:05 gfredericks: Glenjamin: so this is just some weird feature nobody uses that allows you to return a handler?

13:05 Glenjamin: pretty much, although i think i might start using it now

13:05 gfredericks: haha

13:05 Glenjamin: i was trying to figure out how to compose my app the other day

13:06 ended up using (context) a bit

13:06 gfredericks: Glenjamin: well thanks for investigating

13:06 Glenjamin: you can also return an IDeref according to this

13:08 umpa: How do I get the second value from each vector ? {0 [[0 1 2] [0 3 6] [0 4 8]], 6 [[6 7 8] [0 3 6] [2 4 6]]}

13:09 in a form of {0 [2 3 4], etc..

13:09 {0 [1 3 4], etc.. *

13:10 skratl0x1C: How can I create a macro that concats/join/w'ever 2 seqs, one created internally in the macro, the other provided by caller

13:11 I tried these https://gist.github.com/skrat/731f2e8e4bfa4e252c67 both fail

13:12 the 1st one works when I create the 'headers' vector in the macro calling list, but fails when I give it a var instead

13:13 joegallo: why a macro?

13:15 skratl0x1C: joegallo: because it reads a file and joins its content with the args

13:15 it's meant for ClojureScript as a way of embedding assets (GLSL shaders) in the source

13:17 joegallo: umpa: (into {} (for [[k vs] your-thingy] [k (map second vs)]))) is a bit brute-force, but should do the job.

13:22 umpa: or for that matter, https://github.com/amalloy/useful/blob/develop/src/flatland/useful/map.clj#L47 would simplify my version nicely

13:22 technomancy: #=(alter-var-root #'clojure.core/*loading-verbosely* (constantly true)) ; <- clojure.lang.PersistentList cannot be cast to clojure.lang.Var

13:22 why is read-eval so weird?

13:23 umpa: joegallo: nice im going to try it both ways.

13:23 technomancy: I get that the reader hasn't been invoked yet, but this breaks too: #=(alter-var-root (resolve clojure.core/*loading-verbosely*) (constantly true))

13:23 hiredman: technomancy: arguments are not evaluated

13:31 technomancy: yeah... weird stuff

13:37 arrdem: hiredman: ping

13:37 llasram: So it's more like "read–macro-eval"

13:46 Raynes: devn: Holy new clojars.

13:46 gg

13:46 arrdem: wp no re

13:48 justin_smith: mdallastella: re caribou, thanks for the feedback, and re "only a couple of dependencies" its a trick, because those deps are just modularized parts of caribou, and in total the deps are actually quite extensive

13:53 dbasch: clojars looks MUCH better

13:55 justin_smith: gfredericks: defroutes is meant to return a handler, that way you can wrap the handler in middleware etc.

13:55 I thought that was like the normal thing to do with compojure

13:56 arrdem: yay even has the markdown badge snip!

13:57 daGrevis: yelp! http://clojuredocs.org/clojure_core/clojure.core/_dot_dot

13:57 what does .. do?

13:57 cbp: (doc ..)

13:57 clojurebot: "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."

13:58 pyrtsa: daGrevis: (.. foo bar (baz quux)) is the same as (-> foo (.bar) (.baz quux))

13:58 sorenmacbeth: cccccccc

13:58 justin_smith: pyrtsa: and that is the same as (-> foo .bar .baz quux)

13:58 pyrtsa: justin_smith: Careful!

13:58 justin_smith: ?

13:58 that's how the macro works

13:59 pyrtsa: You're right with (.bar) === .bar in there, but quux was an argument.

13:59 justin_smith: ahh, missed that

13:59 because of how the line wrapped

14:00 ,(-> "hello" .length .getClass)

14:00 clojurebot: java.lang.Integer

14:00 gfredericks: justin_smith: no it's not that defroutes itself returned the handler, it's that it had: (GET "" [] (return some handler))

14:00 daGrevis: pyrtsa, thanks mate

14:00 justin_smith: ahh

14:01 pyrtsa: daGrevis: I prefer to stick to -> only, but some like .. more.

14:02 daGrevis: pyrtsa, i'm going through om tut for clojurescript and other used ..

14:02 literally i have no idea about whatever :) much magic to me

14:02 s/other/author/ wtf me

14:02 justin_smith: .. is only for method chaining, -> can chain methods and functions

14:02 technomancy: iirc .. is vestigial

14:03 Glenjamin: hah, i like that idea

14:06 kzar: Raynes: cheers dude :)

14:06 Raynes: kzar: ohi there

14:08 kzar: :p

14:14 benzap: was wondering, what's the clojure equivalent of Foo.class, for the class foo?

14:15 hyPiRion: benzap: Foo

14:15 justin_smith: ,(= (class "hello") 'java.lang.String)

14:15 clojurebot: false

14:15 justin_smith: ,(= (class "hello") java.lang.String)

14:15 clojurebot: true

14:15 hyPiRion: justin_smith: no need to quote it

14:15 justin_smith: right

14:15 hyPiRion: ,(= (class "f") String)

14:15 clojurebot: true

14:15 benzap: ah ok

14:16 justin_smith: classes are first class in clojure

14:18 benzap: so (class Foo) and Foo are equivalent?

14:18 hyPiRion: No, (class Foo) is Class

14:18 ,(class String)

14:18 clojurebot: java.lang.Class

14:19 hyPiRion: (class x) means "I want the class of x". If x is a class, then its class is Class.

14:20 benzap: so would (class Foo) mimmick the functionality of Foo.class?

14:20 hyPiRion: Talk about going complete meta there, btw.

14:20 hiredman: benzap: no

14:20 AimHere: ,(class class)

14:20 clojurebot: clojure.core$class

14:20 hiredman: String in clojure is String.class in java

14:20 TimMc: ,(class nil)

14:20 clojurebot: nil

14:21 hiredman: clojure resolves String to the class object

14:21 benzap: ah, so I just want to call Foo

14:21 Foo --> Foo.class

14:21 hiredman: no

14:21 TimMc: benzap: Well, you cna't call classes.

14:21 hiredman: classes doesn't implement IFn

14:21 TimMc: benzap: Whatcha trying to do?

14:21 benzap: TimMc: Intent mainServiceIntent = new Intent(context, MainService.class);

14:22 TimMc: benzap: (Intent. context MainService)

14:22 benzap: I have this http://pastebin.com/26rAtQ0E

14:22 hmm

14:22 TimMc: (class MainService) should be just MainService

14:23 justin_smith: TimMc: it should be java.lang.Class

14:23 oh wait, misunderstood you, n/m

14:23 benzap: so MainService is MainService.class in java, or am I going crazy

14:23 TimMc: benzap: That's right.

14:23 justin_smith: I kind of wish (class nil) yielded java.lang.Void

14:24 benzap: so like this http://pastebin.com/WN3rk8xW

14:24 TimMc: It's sooorta what that's for.

14:24 benzap: Yep.

14:26 hyPiRion: ,(alter-var-root #'class (fn [f] (fn [x] (if x (f x) Void))))

14:26 clojurebot: #<sandbox$eval25$fn__26$fn__27 sandbox$eval25$fn__26$fn__27@7a4593>

14:26 hyPiRion: ,(class nil)

14:26 clojurebot: java.lang.Void

14:26 hyPiRion: TimMc: I fixed it for you

14:27 justin_smith: ,(class false)

14:27 clojurebot: java.lang.Void

14:27 justin_smith: :P

14:27 hyPiRion: hurray, the return of the nullpointerexception bug

14:28 TimMc: See, shoulda used if-some

14:29 hyPiRion: yeah.

14:29 TimMc: ,*clojure-version*

14:29 clojurebot: {:major 1, :minor 6, :incremental 0, :qualifier #<Void >}

14:29 TimMc: haha

14:29 ,nil

14:29 clojurebot: #<Void >

14:29 justin_smith: lol

14:29 arrdem: oh dear

14:29 justin_smith: ,false

14:29 clojurebot: #<Void false>

14:30 justin_smith: ,true

14:30 clojurebot: true

14:30 arrdem: ,(+ 3 4)

14:30 clojurebot: eval service is offline

14:30 TimMc: >_<

14:30 hyPiRion: Hey was that my fault

14:30 TimMc: Oh, I was going to fix it.

14:30 arrdem: TimMc: I may just be banned, see if you can eval something

14:30 hyPiRion: ,(+ 3 4)

14:30 umpa: ,(into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [(set/intersection #{0 1 2} (set v))])) this is not working

14:30 clojurebot: 7

14:30 #<CompilerException java.lang.RuntimeException: No such namespace: set, compiling:(NO_SOURCE_PATH:0:0)>

14:31 arrdem: ~source

14:31 TimMc: ,(alter-var-root #'class (fn [x] (if (nil? x) x (.getClass x))))

14:31 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>

14:31 Glenjamin: ,(into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [(clojure.core/set/intersection #{0 1 2} (set v))])) this is not working

14:31 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>

14:32 Glenjamin: ,(into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [(clojure.set/intersection #{0 1 2} (set v))])) this is not working

14:32 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>

14:32 Glenjamin: ,(into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [(clojure.set/intersection #{0 1 2} (set v))]))

14:32 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>

14:32 Glenjamin: hrm, one sec

14:32 hyPiRion: Glenjamin: what are you trying to do?

14:32 Glenjamin: trying to see what's up with umpa's thing

14:33 TimMc: ,(alter-var-root #'class (constantly (fn [x] (if (nil? x) x (.getClass x)))))

14:33 umpa: I am trying to get all the val and do intersection

14:33 clojurebot: #<sandbox$eval363$fn__364 sandbox$eval363$fn__364@101812b>

14:33 hyPiRion: That is probably because the vector contains a single element only, not two elements

14:33 TimMc: ,(map class [nil 1 false])

14:33 clojurebot: (nil java.lang.Long java.lang.Boolean)

14:34 Glenjamin: oh right, umpa you need a "k" in that vector

14:34 justin_smith: umpa: that fails at the into {} stage, you are feeding it with a one arg vector

14:34 build up from the inside out

14:35 benzap: i'm extending a class into clojure using (gen-class), if I overload a particular method, and return the wrong type, would you suppose it would return a null pointer?

14:39 justin_smith: benzap: I wonder if it would maybe not be recognized as the method you mean to overload, but a new overload of the method with a different return type. Or maybe trying to do that would be erroneous.

14:39 but unless someone else has a better idea, I'd say try it and see

14:39 benzap: from what I can tell, it doesn't appear to be my problem anyways

14:40 umpa: ,(for [v [[1 3 4] [7 3 4] [1 5 4] [7 5 4]]] [(set/intersection #{0 1 2 3} (set v))]) kinda works

14:40 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: set, compiling:(NO_SOURCE_PATH:0:0)>

14:40 umpa: ,(for [v [[1 3 4] [7 3 4] [1 5 4] [7 5 4]]] [(clojure.set/intersection #{0 1 2 3} (set v))]) kinda works

14:40 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:0:0)>

14:40 justin_smith: for javac, "The compiler does not consider return type when differentiating methods, so you cannot declare two methods with the same signature even if they have a different return type." - dunno how this applies to the clojure bytecode compiler though

14:41 umpa: ,(include 'clojure.set)

14:41 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: include in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:42 justin_smith: that's require

14:42 umpa: ,(require 'clojure.set)

14:42 clojurebot: nil

14:42 umpa: ,(for [v [[1 3 4] [7 3 4] [1 5 4] [7 5 4]]] [(clojure.set/intersection #{0 1 2 3} (set v))]) kinda works

14:42 clojurebot: ([#{1 3}] [#{3}] [#{1}] [#{}])

14:42 justin_smith: the issue here is that you can't put that in a map, because there are no keys provided, just the vals

14:43 umpa: justin_smith: you mean as set/intersection args /

14:43 justin_smith: umm, no, set/intersection worked just fine there

14:44 I mean the previous thing, where you tried to turn that into a map

14:44 umpa: gotcha

14:45 ,(for [v [[1 3 4] [7 3 4] [1 5 4] [7 5 4]]] [(count (core.set/intersection #{0 1 2 3} (set v)))]) is what I actually need

14:45 clojurebot: #<CompilerException java.lang.ClassNotFoundException: core.set, compiling:(NO_SOURCE_PATH:0:0)>

14:45 umpa: ,(require 'clojure.set)

14:45 clojurebot: nil

14:45 umpa: ,(for [v [[1 3 4] [7 3 4] [1 5 4] [7 5 4]]] [(count (core.set/intersection #{0 1 2 3} (set v)))]) is what I actually need

14:45 clojurebot: #<CompilerException java.lang.ClassNotFoundException: core.set, compiling:(NO_SOURCE_PATH:0:0)>

14:45 umpa: ,(for [v [[1 3 4] [7 3 4] [1 5 4] [7 5 4]]] [(count (clojure.set/intersection #{0 1 2 3} (set v)))])

14:45 clojurebot: ([2] [1] [1] [0])

14:53 arrdem: Bronsa: ping

14:54 Bronsa: arrdem: pong

14:54 justin_smith: ,(clojure.set/intersection #{0 1 2 3} [0 1]) umpa: btw this works

14:54 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

14:55 justin_smith: ,(require 'clojure.set)

14:55 clojurebot: nil

14:55 justin_smith: ,(clojure.set/intersection #{0 1 2 3} [0 1]) umpa: btw this works

14:55 clojurebot: [0 1]

14:55 amalloy: TimMc: i don't understand. were you saying that java.lang.Void is "for" the class of null?

14:56 arrdem: Bronsa: I'm considering patching tanal to add :context types for invoke targets rather than expression forms. Also kinda considering a :binding context. Thoughts?

14:56 Bronsa: the problem I'm trying to solve is determining when a {:op :var} is bound to something that's invoked or directly invoked as opposed to taken as a value.

14:57 the former probably being a special case that constant propagation would reveal.

14:57 TimMc: amalloy: I was, but I'm not now. I got confused because Clojure treats the value of a void method call as nil.

14:58 amalloy: aww. can't you go back to being wrong? i like educating people

14:58 TimMc: and so many languages do use a nil response instead of having *no* return value.

14:59 amalloy: I can pretend to still hold that opinion if it would make you happy.

14:59 Bronsa: arrdem: interesting

15:01 arrdem: personally, I wouldn't object to that, I can see why that would be helpful

15:01 arrdem: Bronsa: I can trivially collect all {:op :invoke}s and their targets, and I think that if I just treat all vars in binding forms to be taken as values then I would get a _correct_ abet suboptimal analysis.

15:01 without patching tanal.

15:01 umpa: justin_smith: something like this should work too right (into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [(count (clojure.set/intersection (set comb) v))]))

15:01 justin_smith: something like this should work too right (into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [(count (clojure.set/intersection (set comb) v))]))

15:02 Bronsa: arrdem: it would probably be better to move to namespace qualified contexts at that point, so that we could have :ctx/invoke derive from :ctx/expr

15:02 umpa: ,(into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [(count (clojure.set/intersection (set comb) v))]))

15:02 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:0:0)>

15:02 arrdem: Bronsa: a legitimate use for higherarchies! at last!

15:02 :P

15:03 justin_smith: umpa: no, because you still only have one element in that vector

15:03 umpa: maybe you want ((juxt count identity) (clojure.set/intersection ...))

15:04 but then, you would have identical counts clobbering one another, which is why I used reduce instead of for or map in previous examples

15:04 Glenjamin: ,(do (require 'clojure.set) (into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [k (clojure.set/intersection #{0 1} (set v))])))

15:04 clojurebot: {0 #{1}, 6 #{}, 2 #{1}, 8 #{}}

15:05 umpa: justin_smith: would I need "for" if i used that

15:05 justin_smith: no, reduce and for are two different ways to walk a collection

15:05 Glenjamin: umpa: what is it you're actually trying to do, in terms of data in -> data out

15:08 umpa: Glenjamin: your code gives what I want, maybe vector for the val instead of hash

15:08 Glenjamin: data in would be a map with key val

15:12 Bronsa: arrdem: as I've said, I'm not against the idea; probably worth discussing with tbaldridge though, I remember him telling me a while ago that Rich was not really happy about the :expression/:statement dichotomy, he might have some valuable opinion on this

15:14 arrdem: Bronsa: willco. Doing this "target rather than value" analysis is a pretty trivial post-walk now that I think about it so I'll just do it in Oxcart and whenever Oxcart get taken apart into contribs we can sort that out if I haven't been able to remove it due to folding.

15:15 Bronsa: arrdem: fine with me

15:15 Raynes: kzar: Turns out there were also breaking changes in that patch release. Oops.

15:16 umpa: Glenjamin: how would I get count of the output vals

15:16 bbloom: Bronsa: i'm not sure i follow your comment about the expression/statement dichotomy as it relates to :context

15:16 dkinzer: fg

15:16 bbloom: Bronsa: are you saying that rich wasn't happy that the analyzer behaves differently with respect to :context ?

15:16 Glenjamin: ,(do (require 'clojure.set) (into {} (for [[k v] {0 [1 3 4], 6 [7 3 4], 2 [1 5 4], 8 [7 5 4]}] [k (count (clojure.set/intersection #{0 1} (set v)))])))

15:16 clojurebot: {0 1, 6 0, 2 1, 8 0}

15:16 Glenjamin: like that?

15:17 umpa: Glenjamin: nice

15:17 Glenjamin: if you extract the input into a var with (def), then play around in the repl it should be easier to follow what's going on

15:18 bbloom: Bronsa: looking at tools.analyzer & tools.analyzer.jvm, it seems it only generates :context, never really consuming it except in one place to clear locals... of course the generators are going to care about return position quite a bit

15:19 Bronsa: bbloom: there might be some information loss here since I'm reporting what tbaldridge told me Rich told him, but from what I understood Rich didn't like the fact that ta had an explicit :statement context since Lisps don't really have any statement construct

15:20 arrdem: meh... model != implementation

15:20 bbloom: Bronsa: gotcha. but :statement is really just shorthand for :expr who's value is ignored

15:20 :-)

15:20 Bronsa: bbloom: tej uses :statement to understand when/where it needs to pop a value from the stack

15:21 bbloom: Bronsa: yeah, that of course makes sense

15:21 instead of :context => :expr :return :statement

15:21 Bronsa: so having it is actually useful

15:21 bbloom: you could have :tail? and :used?

15:21 but :tail? true and :used? false wouldn't ever make sense

15:22 arrdem: bbloom: potentially it would if you're inlining or something and the tail value of a subexpression is ignored, ala (do (do .. ) )

15:22 bbloom: hm, that's true

15:22 arrdem: but that's already covered by :ret as opposed to :expr

15:23 Bronsa: bbloom: I don't really see how that would be an improvement over :context :)

15:23 bbloom: yeah, i don't know the precise keywords, just conceptually... what are they precisely? :stmt :ret and :expr ?

15:23 this is IMO, the case for making _ a special variable

15:24 ,(let [_ 1] _)

15:24 &(let [_ 1] _)

15:24 clojurebot: 1

15:24 lazybot: ⇒ 1

15:24 umpa: Glenjamin: yeah repl is nice

15:24 bbloom: c'mon bots

15:24 anyway

15:26 i'm back, stupid irc

15:26 if you say _ is a blackhole value, then do is a special case of let

15:26 arrdem: bbloom: black hole is dangerous in a language where forms must be evaluated for side effects.

15:27 then you get silly people like me who want to throw away unreached pure forms

15:27 bbloom: arrdem: it's only dangerous if your optimizer is broken :-P

15:28 obviously all clojure forms are lifted in to a context in which JVM effects exist :-)

15:28 so really you're getting (JVM ctx ret) and binding ret to _

15:29 which means that you really can throw out some work if you're black holign something... as long as you run the expression up to it's last side effect

15:29 tbaldridge: Bronsa: I wouldn't take Rich's problems with :statement/:expression too seriously, it was more off hand. Knowing what I know now I would probably support the way you do it now. It's sometimes easier to do code emission if you know more about the context

15:30 bbloom: ,(let [x (atom 1), _ (do (swap! x inc) (swap! x * 2) 123)] @x)

15:30 clojurebot: 4

15:30 bbloom: same as:

15:30 ,(let [x (atom 1), _ (do (swap! x inc) (swap! x * 2))] @x)

15:30 clojurebot: 4

15:39 arrdem: Bronsa: okay I can't just clobber :context because I'll break tejvm, so I'm gonna use ::context and lob a :context higherarchy patch at you later.

15:43 Bronsa: tbaldridge: noted, thanks

15:44 arrdem: jeez, make up your mind! :)

15:44 arrdem: Bronsa: quiet you

15:44 /s

15:45 Bronsa: I was just getting ready to be offended for life.

15:45 arrdem: as long as you take patches and feature requests I don't really care one way or the other :D

15:46 Bronsa: ;_;

15:46 arrdem: <3

15:48 bbloom: i absolutely love that i can prn a GIANT expression to a file, change a boatload of code, then just slurp that expression back in and = it to make sure i didn't break anything

15:48 <3 values

16:16 sveri: Hi guys, I am the author of friendui a wrapper which sets a web ui on top of friend and stores the user data in datomic, now, after watching "simplicity matters" the third time it occured to me that I am complecting a friend user interface with datomic and I got the idea to just set a UI on top of friend which accepts some callbacks to load and store user data so that ppl can use every datastore they want, what do you think of this?

16:18 technomancy: I think that writing open source code that depends on proprietary software is silly.

16:20 tbaldridge: sveri: abstraction is often a good idea. Why not use protocols instead of callbacks?

16:20 whodidthis: stupid sexy datomic

16:21 tbaldridge: technomancy: frendui - "a web frontend for friend connected to datomic" kindof seems like the point of the project.

16:22 technomancy: tbaldridge: I understand that

16:22 Glenjamin: abstracting the user storage seems like it would broaden the appeal, certainly

16:23 microamp: tbaldridge: i wonder if rich hickey/cognitect had considered neo4j-like licensing for datamic? (https://github.com/neo4j/neo4j)

16:24 sorry if it has been mentioned earlier

16:24 kbaribeau: hey, is this a known eyesore with dashes in namespaces and using defrecord/java-interop? https://gist.github.com/kbaribeau/d0d94c02a598490653de

16:24 sveri: I need this library for a private project where we use datomic, however, it occured to me that it might be possible some we may use some different storage in a different project

16:24 I think I will decouple it

16:25 mdeboard: microamp: I've wondered that myself, but I suppose they want to spend their time building a product vice building a service-oriented company

16:25 sveri: tbaldridge: I have not used protocols yet, my idea was to pass some functions to friendui to retrieve a list of users and things

16:26 tbaldridge: sveri: probably better to define a protocol, and then pass an instance to frendui. That way all the functions are in one thing, instead of having to pass multiple callbacks

16:26 amalloy: kbaribeau: it's a known issue, but it seems to come up pretty rarely, somehow. i guess just avoid putting new types in namespaces with dashes

16:26 sveri: tbaldridge: a protocol that defines functions to retrieve a list of users, save a user instance, update a user instance etc?

16:27 amalloy: usually there's a more clever way to namespace stuff anyway: my.project.protocols instead of my-project.protocols, for example

16:28 tbaldridge: microamp: to be honest, I've never really cared enough to look into it (I'm not part of the Cognitect product team). Personally I've used proprietary software so much in my career using it doesn't bother me at all. Better to use good tech, IMO, then wine about it not being OSS.

16:28 *whine

16:29 not to mention that I consider GPL to be a rather horrible license.

16:30 hiredman: tbaldridge: calling open source software advocates whiners seems needlessly pejorative

16:30 kbaribeau: amalloy: thanks, I kind of suspected it might be that way

16:32 catern: hiredman: don't try to correct him - it marks him as stupid very quickly so others don't have to waste time

16:32 arrdem: wooooah

16:32 tbaldridge: hiredman: advocating is fine, complaining that some tech isn't OSS is. If I want to write OSS software that's awesome, but why should I complain when some cool tech isn't?

16:33 If I spent 2+ years of my life writing some cool tech, why should people complain when I don't want to give away all my hard work? I just don't understand it.

16:33 catern: tbaldrige: things being open source isn't about them being available for free

16:33 microamp: tbaldridge: i see, thanks for sharing your thought btw

16:34 technomancy: well, this *is* freenode

16:35 TimMc: tbaldridge: Because they want to modify it?

16:35 tbaldridge: catern: in a sense it does, if you read my source, you now know my algorithms. What's left then? patents?

16:35 hiredman: tbaldridge: I think you are painting with a very wide brush there

16:36 tbaldridge: open source is a lot of things, but, for example, datomic has free editions you can use, I doubt that in any way has stopped people from asking about it being open source

16:36 tbaldridge: hiredman: agreed, but doesn't everyone on this subject? :-)

16:36 hiredman: so obviously people are just looking to get it for "free"

16:36 tbaldridge: hiredman: why is the free version not enough?

16:36 technomancy: tbaldridge: vendor lock-in

16:36 Glenjamin: because people want to build their businesses on software without paying for it, clearly

16:37 catern: tbaldridge: no, you didn't read what I said. It isn't about getting your algorithms for free. It's about, for example, not tying my company or technology to your whims

16:37 hiredman: tbaldridge: hard to say, I, for example, would just be interested in looking through the code

16:37 arrdem: catern: all you said was that tbaldridge could be discarded as a fool for disagreeing with you :P

16:37 tbaldridge: hiredman: as would I :-)

16:38 hiredman: tbaldridge: for example at work we use elasticsearch rather extensively, and while I don't like doing it, from time to time it is helpful to look through the code instead of treating it as a black box

16:38 catern: arrdem: actually, I foolishly said something else after that, sigh

16:38 Glenjamin: the lock in point seems pretty solid

16:38 dinduks: Hello

16:39 Glenjamin: but i guess that's the price you have to pay if you want to use it

16:40 arrdem: I get the "but I want to modify it" argument, sort of, but I fail to see the lock in one. As Dalvik is unfortunate proof it is possible to do a clean room implementation of a closed API.

16:40 catern: feel free to charge me, please charge me, for commercial access to your open source project. I have no opposition to paying, just to paying for things that don't give me some basic freedoms about how I use them

16:40 tbaldridge: arrdem: or not, since they still got sued for it.

16:41 arrdem: tbaldridge: that's the point unfortunately.

16:41 dinduks: I was wondering if there were CLJS "frameworks" similar to Meteor or MEAN, that can allow fast (and spectacular) development of web apps. Anything?

16:41 gtrak: dinduks: seen om yet?

16:41 technomancy: arrdem: possible doesn't mean practical

16:41 Glenjamin: arrdem: take MySQL for example - people decide they don't like the Oracle direction, so they take the open source and fork

16:41 technomancy: no libre implementation exists in the real world

16:42 arrdem: technomancy: fine, but if you decided it was cost effective you could build one

16:42 tbaldridge: Glenjamin: note that that project started as OSS originally.

16:42 arrdem: technomancy: the point to me of purchased software is rewarding someone else for incurring the risk of building something nontrivial.

16:42 Glenjamin: yes, that's my point

16:42 arrdem: technomancy: and escaping the cost of doing so yourself

16:42 technomancy: arrdem: doesn't mean there's no lock-in

16:42 gtrak: dinduks: I think the closest thing to full-stack is hoplon http://hoplon.io/, look at pedestal too.

16:42 Glenjamin: if its OSS, you cannot be locked in if you don't like the vendor's direction

16:43 financing OSS is, it seems, a fairly hard open problem

16:43 catern: arrdem: open source software can be "purchased software", weren't you just mentioning neo4j?

16:44 Oh that was someone else. Anyway.

16:44 tbaldridge: Glenjamin: so yes, that's the price you pay with any non-OSS tech. Having used so much proprietary software in my life, and having experienced so little vendor lock-in I guess it doesn't bother me.

16:44 arrdem: technomancy: as long as copyrights and patents don't prohibit clean room implementations (which they seem to do so this is a moot point) my point is that lockin is or should be a non-issue because it's a risk you have to incur if you decide that mitigating that risk by cloning isn't viable.

16:44 Glenjamin: you haven't experienced lock-in, or you haven't had problems because of it?

16:45 technomancy: arrdem: theoretically correct. yet completely impractical

16:45 catern: tbaldridge: doubtful. I think you're just used to the vendor lock in and don't even notice it anymore, you perhaps think that is just how software is

16:45 tbaldridge: But bringing the conversation back around, I just don't understand the need to say "building OSS that requires proprietary software is silly".

16:45 arrdem: technomancy: given that we have retarded IP laws sure

16:45 gtrak: tbaldridge: apparently microsoft is pretty aggressive about deprecating APIs.

16:45 Glenjamin: i agree with tbaldridge there, dependant on proprietary or not, open source is better than not

16:45 technomancy: arrdem: completely impractical even modulo legal issues

16:46 PigDude: what is -Werror in clojure? I have reflection warnings of unknown origin

16:46 hiredman: there is a, I dunno what you call, a margin cost? we store a lot of data on s3 in various formats, I think something like datomics model would work well for us, but it is sort of outside of the use cases that the company seems to be focused on (s3 storage isn't "fast" enough for a real time database backend), and even if it was I don't know that the storage is enough of a problem for us to go out and buy something

16:46 PigDude: i need to see a stacktrace when this happens.

16:46 Glenjamin: reflection warnings usually come with a file and a line

16:46 amalloy: PigDude: there is no stacktrace to be had, because those get generated when your code is being compiled, not when it's being run

16:46 PigDude: that they do

16:47 technomancy: arrdem: that's like saying it's fine to deploy on Windows because ReactOS exists

16:47 PigDude: amalloy: makes sense

16:47 amalloy: however this reflection warning comes from inside of clojure.java.jdbc

16:47 Glenjamin: that's odd

16:47 PigDude: amalloy: i guess i do not have the power to correct it if it happens when compiling java.jdbc

16:47 technomancy: curl http://p.hagelb.org/nope.gif | display

16:48 Glenjamin: PigDude: what version/file/line ?

16:48 tbaldridge: technomancy: are you suggesting it's wrong to deploy Windows?

16:48 PigDude: Glenjamin: 148 in jdbc.clj, where it is parsing a query string. my code doesn't use a query string, so i should've discerned that this is not my problem

16:49 stompyj: (into {} coll) seems quite with large hashes. Is there a quicker way to do this?

16:49 technomancy: tbaldridge: not like ... morally wrong

16:49 Glenjamin: PigDude: in 0.3.3 that function looks to have the correct typehint https://github.com/clojure/java.jdbc/blob/java.jdbc-0.3.3/src/main/clojure/clojure/java/jdbc.clj#L141

16:49 technomancy: just that if you ever find yourself in a position where that seems reasonable, you need to seriously re-evaluate the life choices that led you to this point

16:49 amalloy: Glenjamin: it's https://github.com/clojure/java.jdbc/blob/java.jdbc-0.3.3/src/main/clojure/clojure/java/jdbc.clj#L147

16:49 justin_smith: stompyj: there is also (apply hash-map coll), but into should be faster

16:50 Glenjamin: amalloy: oh right, no hint on the .split retval

16:50 stompyj: justin_smith: I’lll try that, thanks. I would have never guessed that method would so be slow

16:51 Glenjamin: stompyj: have you profiled?

16:51 PigDude: Glenjamin: it is the correspondence between .getQuery and .split, it seems

16:51 amalloy: Glenjamin: well, actually, i guess it's the next line. that first .split is fine, because query's type is known. but the type of kvs is not

16:51 (which, by the way, should really be called kv, not kvs)

16:51 Glenjamin: yeah, needs ^String kvs

16:51 PigDude: ah right it's all in the for loop :)

16:52 *comprehension

16:52 stompyj: Glenjamin: I just ran (time (into {} return-val)) and it’s taking ~20-30ms

16:52 O_o

16:52 PigDude: thanks Glenjamin, amalloy

16:52 Glenjamin: and what is return-val? a large lazy sequence?

16:52 mdeboard: I'd rather read a spirited/occasionally mean argument about OSS than that one ebaums world porn spammer

16:52 or whatever

16:52 that was weird

16:52 stompyj: Glenjamin: yeah

16:52 tbaldridge: technomancy: it's that assumption I kick against. The idea that if I wish to deploy Windows (or proprietary software in general), there is something wrong with me. But we've digressed so much at this point I suppose I should let it drop.

16:53 Glenjamin: you may find that most of the time is reading the sequence, rather than building the map

16:53 but yeah, jvisualvm is probably a good place to start

16:53 technomancy: eh, kick all you want

16:53 stompyj: awesome, thank you

16:53 justin_smith: PigDude: also, if the coll is lazy, you may find performance is better if you don't hold the head of the sequence

16:54 tbaldridge: technomancy: I see no problem with well written proprietary software. Hence the reason I tend to use Macs over Windows/Linux...it just works for me. I know it doesn't for everyone.

16:54 PigDude: stompyj: ^

16:54 stompyj: was for you i think

16:54 amalloy: that sounds like a complete red herring, justin_smith

16:54 stompyj: PigDude / justin_smith thanks

16:54 PigDude: stompyj: heh i didn't help you :)

16:55 justin_smith: oops, I replied to PigDude by mistake about stompyj's question, oops

16:55 michaniskin: is the correct way to deprecate functions demonstrated in the core.memoize https://github.com/clojure/core.memoize/blob/master/src/main/clojure/clojure/core/memoize.clj#L188-L191 ? or is there another, better way i should be doing it?

16:56 tbaldridge: michaniskin: why not just add it to the doc string?

16:56 michaniskin: and to the changelog. If people don't read the change log, their bad for upgrading before reading.

16:57 michaniskin: tbaldridge: i'd like to have something displayed to the user at compile time telling them how to use the new replacements, maybe? i know people should read the changelog but i thought this might help the rest of the people

16:58 stompyj: Glenjamin: if reading the sequence is indeed the issue, what is the idiomatic way to fix that?

16:58 michaniskin: is it a bad idea to print warnings like this at compile time?

16:59 technomancy: michaniskin: the only danger there is non-aot'ing users might miss it.

16:59 amalloy: stompyj: the point is that *producing* the sequence may be slow, just because there's a lot of work to do. you can't tell just from running (time (into {} xs)) that anything is slower than it should be

17:00 technomancy: michaniskin: one thing I have done with Lein is have the deprecated function force a delay that prints a warning, so it only happens once

17:00 stompyj: amalloy: hmmm. fair enough, makes sense

17:00 technomancy: michaniskin: I mean when it's run

17:01 michaniskin: technomancy: you're saying if they aren't AOTing the warning might not print when the macro is used? Also, I like the delay idea

17:01 stompyj: as with most things in life, I can fix this by fixing my data model, however, I’m more curious about looking into this behavior, since I hadn’t had to deal with it before

17:01 thanks

17:02 tbaldridge: michaniskin: you can do what you want, but if it were me, I'd just rip out the old code, put in the new code, put a note in the changelog and the release email, and reduce the size of that file by 50%. But I can see why you're doing it this way.

17:02 dinduks: gtrak: thanks. i'll check these out.

17:02 technomancy: michaniskin: oh, I missed that it was a macro. in that case compile-time is probably fine.

17:03 gtrak: dinduks: om is hard to search for: https://github.com/swannodette/om

17:03 it makes the frontend very fast to build.

17:04 michaniskin: tbaldridge: the old stuff still works fine, but some of the names were really terrible and things like that. i don't mind keeping the old names around forever to keep compatibility but i'd really like to help the user by telling them what the new names are, because i'll be removing the old names from the examples and tutorials etc.

17:20 technomancy: https://i.imgur.com/wfNZNyo.png =(

17:22 gtrak: technomancy: read clojure documentation with Tor.

17:23 technomancy: gtrak: well I don't expect much when I visit clojure.org, but I do have an expectation that I can successfully establish an HTTP connection. =\

17:30 mmmm_: hey guys,

17:32 problems with leiningen and so - I create project with libraries in the deps

17:32 danneu: Something at twitter changed this past month and most of my automated tweets (a few per day) fail with an error 'This request looks like it might be automated.' -- I guess their http POST api was intended for hand-typed curl requests

17:33 I have some audacity

17:33 mmmm_: lein deps works - I run the repl - but I don't access the libraries in the repl

17:33 (use 'seesaw.core) -> nil

17:34 justin_smith: mmmm_: so what's the symptom?

17:34 ,(use 'clojure.set)

17:34 clojurebot: nil

17:34 mmmm_: CompilerException java.lang.RuntimeException: Unable to resolve symbol: frame in ... etc

17:34 Leiningen 2.4.2 on Java 1.7.0_55 OpenJDK 64-Bit Server VM

17:34 justin_smith: ,(ns-publics clojure.set)

17:34 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:0:0)>

17:34 justin_smith: ,(ns-publics 'clojure.set)

17:34 clojurebot: {union #'clojure.set/union, map-invert #'clojure.set/map-invert, join #'clojure.set/join, select #'clojure.set/select, intersection #'clojure.set/intersection, ...}

17:35 justin_smith: mmmm_: if you check the ns-publics, what do you see?

17:35 mmmm_: justin_smith: cannot access symbols

17:35 justin_smith: I mean call (ns-publics 'seesaw.core)

17:35 mmmm_: (ns-publics 'seesaw.core) {foo #'seesaw.core/foo}

17:35 only foo

17:36 justin_smith: mmmm_: did you by any chance try to switch to the seesaw.core ns before requiring it?

17:37 mmmm_: probably not - what is switching? (I call (use 'seesaw.core) before

17:37 justin_smith: try '(require 'seesaw.core :reload)

17:37 without that first '

17:38 amalloy: mmmm_: do you have a file named seesaw/core.clj in your own project?

17:38 mmmm_: did reload - still only foo in the seesaw.core ns

17:38 nope

17:38 ahh yes... aggghhhh

17:39 justin_smith: you shadowed the ns?

17:39 mmmm_: yep

17:39 ...

17:40 danneu: oh, so you must've `lein new seesaw` and it created the seesaw.core/foo

17:40 awesome

17:40 mmmm_: yes

17:41 put to some of your "collected" :)

17:44 danneu: i don't know if i've every really stopped making basic errors that take me 30 min to figure out. like (let [name (:name user)] ...) and then trying to (clojure.core/name ...)

17:46 amalloy: that one's pretty nasty, danneu. i've made it enough times that i generally manage to avoid it or fix it quickly

17:46 but it is not a lot of fun

17:47 technomancy: luckily it only happens with that one function =)

17:47 amalloy: i wonder...if i see "String can't be cast to IFn", is that the first mistake i assume i've made? i've kinda grown up enough that i don't really put in too many parens anymore...what else would cause that exception?

17:48 passing args in the wrong order, i guess: a string where i meant to put a callable and vice versa

17:48 technomancy: amalloy: someone plz write an nrepl middleware to make fun of you for doing that

17:48 amalloy: it won't be me. i'm pretty sure there's no swank middleware support

17:49 technomancy: maybe that'll be the killer feature that finally gets the slime diehards to upgrade

17:49 :repl-options {:sarcastic true}

17:49 amalloy: maybe we can get the vim users on board too

17:49 "a sarcastic repl? sign me up!"

17:50 technomancy: "Finally, your editor can be as tired of these type errors as you are."

17:50 arrdem: technomancy: but then we need to get tanal in between the repl and the compiler..

17:50 danneu: i've also run into issues that throw a generic low level clojure error on line 1, column 1 even though it's because of an ad-hoc `(require '[some.ns])` on line 832 i forgot to remove before rebooting my repl

17:50 technomancy: arrdem: nah just hard-code it to the clojure.core/name bug; that's good enough for an 80% solution

17:51 arrdem: technomancy: dude that's not even a 20% solution...

17:51 technomancy: lets see you write a regex that tracks bindings..

17:51 technomancy: arrdem: I mean based on the "String can't be cast to IFn" message

17:51 * arrdem refrains from ranting about what you can do with tanal analysis

17:53 TimMc: technomancy: Match #"^\s+name\s" and #"\[name\s" and I think you've got a pretty good guess at trouble spots.

17:54 arrdem: or you could just use tanal and (ns-maps) to detect all import shadowing :P

17:55 justin_smith: another big one is count - perfectly cromulent as a noun or verb, so very ready to get shadowed

17:57 amalloy: i've done it with map sometimes

17:57 which is particularly tricky to track down, because maps tend to be callable and just return stupid results

17:58 justin_smith: ouch

17:58 arrdem: IFn ALL THE THINGS

17:58 justin_smith: ahh, especially as you would normally be doing the three arg version, so you get the unmodified sequence back

17:58 lol

17:59 cbp`: except for regex ;(

17:59 amalloy: yep

17:59 seangrove: arrdem: Strings implemented IFn in cljs for the longest time

17:59 Fun times

17:59 arrdem: RFC: me.arrdem/regular: crowbars int core and implements IFn for regexes :P

17:59 s/int/into/g

18:00 technomancy: nothing has ever made me sad about not using cljs like callable regexes

18:02 dgleeson: so when you return a 404 using ring it doesn't add the extra tomcat formatting. I'm curious if anyone has experience munging the error codes so they look like tomcat's default presentation?

18:03 justin_smith: dgleeson: how are you returing the 404 status? {:status 404} with no body key?

18:05 gtrak: tanalysis

18:06 dgleeson: {:status 404 :body "some message"}

18:06 if I return just a status code it's a blank page

18:07 justin_smith: dgleeson: oh, I had hoped that might cause it to use the default 404 body

18:09 dgleeson: My other java servlets use the HttpServletRequest/sendError work flow

18:09 which triggers it

18:10 but since ring-servlet wraps that with a map, I'm not exactly sure how to trigger that code path

18:23 seangrove: dnolen_: Might be time to bump mies-om template

18:28 kzar: Raynes: :o did I mess something up?

18:28 Raynes: kzar: Nope, it was a previous pull request by someone else.

18:28 Just changed some var names.

18:28 I had forgotten about it was was like "RELEASE! RELEASE! RELEASE! SHIPIT!"

18:28 Nothing to be done about it now.

18:29 kzar: llol

18:32 dnolen_: seangrove: ah right, thanks for the reminder

18:32 seangrove: dnolen_: No worries, just coming back to it after some time in the js world

18:38 noncom|2: does anyone know anything about DotLisp?

18:39 what's the project status?

18:40 justin_smith: noncom|2: interesting, looks like a clojure predecessor

18:41 noncom|2: yes, it is, i am to ressurect it for my practice - i have to work with unity3d, which is based on mono, which is based on net framework 2. so far, dotlisp is the only sane lisp for net i have found (besides ironscheme)

18:41 coincidently, it is made by the same man :)

18:42 its crucial +s are 1) net 2.0 compatibility and 2) lightweighness like never before

18:42 so i wanted to know what's up with it officially

18:42 justin_smith: noncom|2: what about the clojure clr backend?

18:43 is that just not usable?

18:43 noncom|2: too bad, but clojure clr requires net 3.5+, it will not work in unity3d

18:43 also, we target android...

18:43 so dotlisp seemes to me like a neat little brother (or sister) of clojure

18:44 the standard boot.lisp defines much, but i am writing boot2.lisp which brings it closer to clojure in terms of functionality

18:44 since i'm used to clojrue :)

18:44 ofcourse, no stm and such, but unity3d hardly requires it

18:45 i wrote a mail from the sourceforge site to both maintainers, but no answer yet...

18:46 i thought about ressurecting it and creating a good unity3d support

18:46 currently unity3d lacks lisp

18:47 so i thought maybe anyone knows, how can i write a mail to rich about it, since that project did not seem to have any community at all..

18:55 TEttinger: noncom|2, are you sure unity allows anything but C#, Boo, and UnityScript?

18:55 I think it has arbitrary constraints

18:56 noncom|2: well, firstly it is based on an ancient mono version, which is about framework 2

18:56 all clr langs moved far since then, as did clojure

18:56 but i want a lisp with a repl

18:56 the only 2 sane candidates are dotlisp and ironscheme

18:57 ironscheme is another story, lets discuss dotlisp

18:57 TEttinger: right but I have never heard of anyone being able to use anything but those 3 in the unity environment

18:57 noncom|2: i have managed to implement a repl and it wokrs perfectly fine

18:57 i already can do anything with it

18:57 TEttinger: mono has a C# repl actually

18:57 noncom|2: but not for unity3d :)

18:57 TEttinger: :-(

18:58 noncom|2: actually, unity3d is a piece of ancient crapware

18:58 (dont tell anyone)

18:58 TEttinger: why not libgdx if you're using clojure?

18:58 hiredman: b

18:59 noncom|2: currently i have a project with libgdx and i also use jmonkey when appropriate, that is fine. but there is a second story in my life - my new employee is based on unity3d

18:59 i am actually a jvm + clojure guy

18:59 TEttinger: heh ok

18:59 noncom|2: but forced to work for a unity3d c# company

18:59 TEttinger: C# isn't that bad, tbh

18:59 noncom|2: if i propose the initiative inside the company, they will accpet it

18:59 TEttinger: LINQ is a nice breath of functional air

19:00 noncom|2: well, i do not like it much, but yeah, the language is ok, on par with java

19:00 but there are other implications too..

19:00 using a lisp will help us much

19:00 and also, i just want to work with a lisp

19:00 :)

19:01 you should try unity3d if you did not have a chance yet

19:01 to see all its crappyness

19:02 TEttinger: heh, I was going to, but I'm sticking with either C#/MonoGame or Java/Clojure/LibGDX

19:02 noncom|2: i vote for java :) since i worked 3 years in that field - java/clojure/jme/libgdx

19:03 i think that seeing some unity3d is useful in terms that you can learn, how you should NEVER design your software

19:03 it has some good spots though

19:03 but they jsut dont cut it

19:15 deathknight: (format "test/%s/foo")

19:15 what does %s mean?

19:15 arrdem: format in a string here

19:15 deathknight: is there a term I can look up that explains what you just said?

19:16 cbp: deathknight: http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

19:16 arrdem: java.lang.String.format

19:17 deathknight: still dont quite understand

19:18 specific example: (api/simple-request (format "/calendars/%s/events" (api/decode cal)) token)

19:18 is token being placed where the %s is?

19:18 cbp: no, (api/decode cal) is assumed to be a string and placed where the %s is

19:18 deathknight: NICE

19:19 thank you!

21:38 Fare: hi

21:39 catern: hi

21:39 Fare: which clojure deftype vs defrecord vs ... to use for data with inheritance of fields?

21:43 justin_smith: Fare: if all you need to do is inherit some default values, you can just call merge on a map

21:43 hellofunk: Fare: while polymorphism is quite nice in Clojure with defrecord, inheritance is a different matter and I think generally not recommended

21:43 as justin_smith notes, using data instead of object-oriented ideas tends to be more idiomatic in Clojure

21:45 Fare: so more like, include a subrecord?

21:45 e.g. if I want each record to contain provenance information

21:46 hellofunk: learn all the functions on maps and you'll likely find some good ones for your purposes. assoc, dissoc, merge might be useful: Fare

21:46 justin_smith: until you absolutely need the performance benefits of a custom deftype or defrecord, use a map, and write a function that makes a map of the right shape

21:47 using maps and using types / records happens to have identical semantics, so upgrading is not very hard

21:48 if you want, you can even name the function returning the map "constructor"

21:48 hellofunk: note that while defrecord supports associative functions, deftype is a much simpler API; I don't think assoc etc work on deftype?

21:48 justin_smith: hellofunk: ahh, good call, maybe not

21:48 that's probably why I have never used it actually

21:49 anyway, at worst it's a question of (.slot thing) vs. (:slot thing)

21:49 hellofunk: generally deftype is not going to be useful unless you want to, for example, write a Clojure compiler for a different platform, you can build out your base with custom types

21:49 justin_smith: (for access that is)

21:51 as I don't use deftype much, this is a helpful reminder of how they work / compare http://clojure.org/datatypes

21:54 Fare: especially not the heading on that page "Datatypes and protocols are opinionated"

22:00 deathknight: using http.async.client, how do I specify the content-type as JSON?

22:03 justin_smith: deathknight: (http/POST client "url" :body [{:mime-type "application/json" ...}])

22:03 https://github.com/neotyk/http.async.client/blob/development/docs.org

22:06 deathknight: I...am...so close....thank you Justin!

22:06 If my body already looks like this, should I still put a vector around it with the inclusion of mime-type? :body {:end {:date "2014-06-16"} :start {:date "2014-06-16"}}

22:07 or would this work-- :body {:mime-type "application/json" :end {...}...}

22:08 * Fare is coming from Common Lisp and learning Clojure

22:08 Fare: clojure in some ways seems to be miles ahead, and in other ways, lagging.

22:08 I'm not yet sure exactly which though.

22:09 justin_smith: Fare: I think clojure is much more opinionated

22:09 Fare: is that your opinion?

22:09 hellofunk: Fare, which ways do you feel clojure is lagging?

22:10 it is fair, Fare, to say that clojure is a bit more encouraging to a particular programming style than is CL

22:10 justin_smith: deathknight: I think the way it works is you make a :query that consists of some magic key, so it's :query {:request (your map that bcomes json here)}

22:11 deathknight: hmm

22:11 looks a bit different than what I'm working off of that works so it's a bit over my head :)

22:11 justin_smith: hellofunk: two ways that I would agree clojure is lagging is startup time and step debugging

22:11 deathknight: I'm doing some finicky balancing on these shoulders

22:12 justin_smith: deathknight: heh, OK

22:12 deathknight: http://neotyk.github.io/http.async.client/doc/http.async.client.html#var-POST

22:12 that's pretty comprehensive I think

22:12 hellofunk: it's definitely true that Clojure debugging is pretty primitive

22:12 deathknight: Danke!!

22:24 so even though content-type is usually defined in the headers, http.async.client has it chosen in the :body?

22:24 justin_smith: the docs may be wrong?

22:24 deathknight: oh! what you were saying earlier with :query!!!

22:24 the json data goes in that!

22:25 holy topanga!

22:25 justin_smith: yeah, query is just part of the body I guess?

22:25 hellofunk: no, when you see a specialist and he says you have the flu and it turns out to be typhoid, *then* the docs are wrong

22:25 deathknight: LOL

22:27 hellofunk: i'm just sayin

22:29 deathknight: So I'm getting clojure. Right now my :body is throwing this-- IllegalArgumentException No matching clause: http.async.client.part/create-part (part.clj:42)

22:29 :body [{:mime-type "application/json"}]

22:29 and here are the docs referencing create-part -- http://neotyk.github.io/http.async.client/doc/http.async.client.part.html

22:29 getting closer*

22:30 justin_smith: oh, in order to submit json does it need to be multipart?

22:31 Fare: well, I miss CLOS

22:31 deathknight: I have no idea

22:31 Fare: I really like the everything-pure-by-default of Clojure.

22:31 I don't understand protocols yet.

22:32 is there no inheritance of methods?

22:32 hellofunk: Fare records and protocols are basically the decoupling of object properties and object methods, makes things a lot more simple and flexible. Can adopt as many protocols as you want.

22:32 justin_smith: a protocol is a more clojure-y view of an interface, which is a class but not really that is there for implementing rather than inheriting from

22:33 deathknight: what multipart type would json require?

22:34 hellofunk: Fare it depends on how you need inheritance. in many languages, inheritance is a prerequisite for polymorphism, and if polymorphism is what you need, you get that in clojure with multimethods without using inheritance

22:35 Fare: no, I want mixins, just like I can have with CLOS.

22:35 mixins are good.

22:35 multiple inheritance

22:36 is there anything in clojure that will let me do multiple inheritance?

22:36 (I suppose I could roll my own on top of maps using macros... bleah)

22:36 hellofunk: Fare, well again it depends on what you need, exactly. You can certainly adopt multiple interfaces, which is similar to multiple inheritance in some languages.

22:37 gfredericks: Fare: the hierarchies used by multimethads support multiple inhertance

22:37 ,(derive ::square ::shape)

22:37 clojurebot: nil

22:37 gfredericks: ,(derive ::square ::word)

22:37 clojurebot: nil

22:37 Fare: hellofunk, except that in CLOS, I can inherit multiple interfaces AND their default (and/or next-method) implementations

22:38 gfredericks: ,(defmulti describe :type)

22:38 clojurebot: #'sandbox/describe

22:38 gfredericks: ,(defmethod describe ::shape [_] "it is a shape")

22:38 clojurebot: #<MultiFn clojure.lang.MultiFn@195d263>

22:38 hellofunk: Fare as gfredericks mentions, check out the derive methods

22:38 gfredericks: ,(describe {:type ::shape})

22:38 clojurebot: "it is a shape"

22:38 Fare: ok

22:38 thanks!

22:38 gfredericks: ,(defmethod describe ::word [_] "it is a word")

22:38 clojurebot: #<MultiFn clojure.lang.MultiFn@195d263>

22:38 gfredericks: ,(describe {:type ::square})

22:38 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Multiple methods in multimethod 'describe' match dispatch value: :sandbox/square -> :sandbox/shape and :sandbox/word, and neither is preferred>

22:39 gfredericks: ,(prefer-method describe ::word ::shape)

22:39 clojurebot: #<MultiFn clojure.lang.MultiFn@195d263>

22:39 gfredericks: ,(describe {:type ::square})

22:39 clojurebot: "it is a word"

22:40 bbloom: Fare: i'm not saying that next-method et al aren't ever useful, but they are A LOT LESS USEFUL than you'd think in clojure

22:41 Fare: it's also pretty easy to merge maps & use ##(doc extend)

22:41 lazybot: ⇒ "([atype & proto+mmaps]); Implementations of protocol methods can be provided using the extend construct: (extend AType AProtocol {:foo an-existing-fn :bar (fn [a b] ...) :baz (fn ([a]...) ([a b] ...)...)} BProtocol {...} ...) extend takes a type/class (or interface,... https://www.refheap.com/86698

22:41 bbloom: so if you really do need concrete "inheritence" you can simply compose maps & call extend

22:41 requires some pre-meditation, but the results are much simpler

22:41 again, i've only ever needed to do this once in practice

22:42 gfredericks: bbloom: is that how CinC would likely handle ASeq and other inheritance patterns in the java code?

22:43 bbloom: gfredericks: one possible way, sure

22:43 deathknight: "post request requires a content-length header"

22:43 justin, does that ring a bell? :O

22:43 bbloom: gfredericks: problem is that for the core-most parts of clojure, best perf is given if interfaces are implemented when classes are defined

22:44 gfredericks: protocols really are quite fast, but for code that is on ALL USERS critical path, the small overhead isn't worth it

22:44 so it's more likely that there'd be some macro-fu with quoted code

22:44 gfredericks: bbloom: ah ha right

22:45 they'll have to bring in ztellman

22:45 amalloy: gfredericks: ztellman has abandoned protocols, last i checked

22:45 uses interfaces instead

22:45 gfredericks: amalloy: sure

22:45 replacing java with a few nested backticks

22:46 bbloom: speaking of odd things w/ protocols

22:47 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AFunction.java#L20

22:47 that's only ever used for protocol stubs

22:47 seems kinda weird to throw an extra field on every function ever

22:49 closing over values makes fields, but you can't have a mutable local... and since protocols are mostly defined in clj, *every* function gets a bonus mutable local in case it might be used for a protocol

22:49 and then ztellman shows up again: https://github.com/ztellman/proteus

22:49 hellofunk: this is some pretty great info

22:50 amalloy: bbloom: do you know if protocol functions still get callsite method caches?

22:51 like, when i write (fn foo [] (proto 1)), where proto is a protocol function, does the class generated for foo's implementation have fields for caching the most-recently-used protocol definition?

22:51 gfredericks: amalloy: isn't that what he linked to?

22:51 amalloy: gfredericks: no, that's a single cache on every function

22:52 gfredericks: and you're talking about a static field?

22:53 amalloy: i'm talking about multiple fields, one for each protocol function that is called

22:53 gfredericks: ah hum

22:53 amalloy: a quick disassemble suggests this is no longer the case

22:54 bbloom: amalloy: i haven't studied the compiler side of protocols too closely yet

22:54 gfredericks: would The BBloom Field serve that purpose then?

22:54 or does it do something else I forgot to understand?

22:54 bbloom: that field is a per-method cache

22:54 not a per-callsite cache

22:54 amalloy: a year or two ago things were arranged such that if you wrote a function that called ten protocol functions, you got like thirty fields, three each for caching each call site

22:55 gfredericks: so what does The BBloom Field accomplish?

22:55 bbloom: side note: if you deftype, then extend-protocol, and keep re-evaling that file while you work... you leak memory :-P

22:55 amalloy: which is fine for functions with only one instance, like (defn foo), but is *terrible* for lambdas that get returned, or things which are instances of a defrecord

22:55 bbloom: not a lot, but a leak is a leak

22:55 ,(defprotocol P (f [x]))

22:55 clojurebot: P

22:55 bbloom: ,(deftype T (f [x] 1))

22:55 clojurebot: #<AssertionError java.lang.AssertionError: No fields vector given.>

22:56 bbloom: ,(deftype T [] (f [x] 1))

22:56 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol>

22:56 bbloom: ,(deftype T [] P (f [x] 1)) ; i suck

22:56 clojurebot: sandbox.T

22:56 bbloom: ,(deftype T [] P (f [x] 2)) ; i suck

22:56 clojurebot: sandbox.T

22:56 bbloom: ,(deftype T [] P (f [x] 1)) ; i suck

22:56 clojurebot: sandbox.T

22:56 bbloom: er i still suck

22:56 ,(deftype T [])

22:56 clojurebot: sandbox.T

22:56 * Fare is learning too many languages at the same time and is getting confused: python, java, clojure, javascript...

22:56 bbloom: ,(extend-type T P (f [x] 1))

22:56 clojurebot: nil

22:56 bbloom: P

22:56 ,P

22:56 clojurebot: {:impls {sandbox.T {:f #<sandbox$eval225$fn__226 sandbox$eval225$fn__226@1ce1b2b>}}, :on sandbox.P, :on-interface sandbox.P, :sigs {:f {:doc nil, :arglists ([x]), :name f}}, :var #'sandbox/P, ...}

22:56 bbloom: ,(-> P :impls count)

22:56 clojurebot: 1

22:56 bbloom: ,(deftype T [])

22:56 clojurebot: sandbox.T

22:57 bbloom: ,(extend-type T P (f [x] 2))

22:57 clojurebot: nil

22:57 bbloom: ,(f (T.))

22:57 clojurebot: 2

22:57 bbloom: ,(-> P :impls count)

22:57 clojurebot: 2

22:57 gfredericks: w00t

22:57 do old classes normally get GC'd?

22:57 bbloom: i have no idea

22:57 i hope so

22:57 amalloy: gfredericks: yes, if there are no references to them

22:58 gfredericks: okay so this is a leak not just in the size of that hashmap but also the classes not getting GCd

22:58 bbloom: gfredericks: right

22:58 b/c the keys are actually the types

22:58 i dunno if this is filed anywhere

22:58 not sure if it matters really though

22:59 Fare: I like the first-class class thing

22:59 bbloom: Fare: that's just standard java

22:59 and it should be standard *everything*, since it was standard in smalltalk back when :-P

22:59 Shayanjm: I wish lighttable addressed issues faster

23:06 trptcolin: bbloom: wow that definitely explains some stuff i’d seen w/ reloading locally

23:06 bbloom: trptcolin: what have you seen?

23:06 trptcolin: i’d assumed it was something in here: http://dev.clojure.org/jira/browse/CLJ-1152

23:07 permgen exploding

23:08 hellofunk: Shayanjm agree. I really have high hopes for light table but my reported issues appear ignored and some things bother me too much, so I switched back to emacs.

23:08 bbloom: trptcolin: if you can create a small project that exhibits the problem in a bad way, please go ahead and file the ticket :-)

23:08 Shayanjm: hellofunk: I'm trying to dive into clojure, and have been using lighttable for its instarepl thing

23:08 but I actually discovered a discrepency in their repl vs. the repl provided by lein

23:08 (which I would assume is a pretty big issue)

23:08 hellofunk: Shayanjm what kind of discrepancy?

23:09 Shayanjm: https://github.com/LightTable/LightTable/issues/1520

23:09 hellofunk: Shayanjm light table is nice for quick start in clojure learning, i like its built-in docs and the automatic inline autocompletion and documentation

23:09 bbloom: hellofunk: don't use `ns to switch between namespaces

23:09 use `in-ns

23:09 (doc in-ns)

23:09 clojurebot: "([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."

23:10 bbloom: (doc ns)

23:10 clojurebot: "([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class ...), when supplied, de

23:10 trptcolin: bbloom: trouble is, (1) it’s just a dev-time thing, (2) it’s with a non-core unit testing library (3) restarting my local test process gets me working again, (4) i’m not even working on that project these days.

23:10 bbloom: trptcolin: yup, dev-time only issue... there are way worse problems that prevent "never restart a repl" from being a reality

23:11 loliveira: hi, does anyone know why i’m getting this error: https://www.refheap.com/86699 ? I am new to clujurescript.

23:11 hellofunk: Shayanjm in your posted issue, it's not clear that you may not have re-evaluated your defs after you switched to the new namespace

23:11 You certainly could have, and maybe you didn't, but if you had, then they'd appear in the new namespace

23:12 bbloom: trptcolin: there, i added a bullet point here: http://dev.clojure.org/display/design/Never+Close+a+REPL

23:12 rather than make an issue, since it will never get fixed :-P

23:12 Shayanjm: hellofunk: That's a good point, I'm not sure if the instarepl automatically re-evaluates every def

23:12 trptcolin: these days i basically only file issues that either force me to monkey-patch core or that i’m certain are bugs that i have the correct fix for

23:12 bbloom: it's a shame, but me too

23:13 hellofunk: Shayanjm in any case, emacs is a much much smoother editor overall

23:13 bbloom: Shayanjm: i meant that msg for you, not hellofunk

23:13 hellofunk: in light table, the actual emphasis on fonts seems to change as you cursor through the code, which is ridiculous.

23:14 Shayanjm: bbloom: oh, I see. I mean either way, that doesn't address the discrepency between Lein & Lighttable REPLs

23:14 there's no reason for one to evaluate differently to the other given the same set of commands

23:14 hellofunk: I should probably pick up emacs then. I'm an ST3 user and thought Lighttable looked interesting

23:14 bbloom: Shayanjm: i think light table does some "clever" bits with respect to ns forms

23:14 hellofunk: Shayanjm bbloom i re-iterate that your test in those screenshots is not a good one unless you are certain the defs were not re-evaluated after you switched ns

23:15 technomancy: hellofunk: how is re-evaluating defs after switching namespaces not broken behaviour though?

23:15 Shayanjm: ^

23:15 hellofunk: technomancy he could have actually re-evaluated the defs manually in the instarepl since they are right there, isn't it easy to evaluate any line in the instasrepl?

23:16 technomancy: Shayanjm: you could check using (meta #'thing2) though just to see what flavour that particular brokenness happens to take

23:16 Shayanjm: hellofunk: All of the code in the instarepl was written inline

23:16 and the issue can easily be replicated

23:17 hellofunk: Shayanjm i will try it out right now on my light table out of curiousity.

23:21 Shayanjm ah, in live mode as you are typing the refer statement, it will refer everything before you get to the :only part of the forum

23:21 *form

23:21 Shayanjm: oh fucking hell

23:21 hellofunk: this is not a bug, it is by design, that is what the "live" mode does

23:21 Shayanjm: well that actually makes me feel a lot better

23:22 hellofunk: you can turn off the live mode, of course

23:22 Shayanjm: thanks for investigating hellofunk

23:22 loliveira: any help? https://www.refheap.com/86699

23:22 hellofunk: Shayanjm i'd recommend updating or closing your Github issue

23:22 it's not a bug

23:22 Shayanjm: Doing so right now

23:23 technomancy: hellofunk: does it eval it before the paren is closed, or is it eval-able because of paredit-ish stuff?

23:23 hellofunk: technomancy it evals immediately everything you type inside a form, and the close paren is already there due to paredit

23:23 it will re-evaluate on every keystroke

23:23 technomancy: wow

23:24 hellofunk: hence the "insta" in "instarepl"

23:24 But there is a Live button right there up front for turning that off

23:24 technomancy: does it have a failsafe to autodetect rm -rf calls? =)

23:25 hellofunk: The screenshot in the github issue indicate that Live mode was on for the test

23:25 Light table is quite interesting and nice in many ways, but my workflow is better for now with emacs

23:26 deadghost: http://stackoverflow.com/questions/24254689/change-vectors-to-lists-using-postwalk

23:27 does this count as a bug and should I report it somewhere?

23:28 hellofunk: Part of the problem with Light Table is that it's most important part - the code editor - is not even written in Light Table. It's a third-party open-source JS library. And the code editor is not that good IMHO. Chris has said that if you want to see the editor improve, you should support that other library as well. And so it's a trickle-down problem of quality.

23:29 deathknight: Getting "UnsupportedOperationException nth not supported on this type: Character" when introducing JSON to an HTTP POST request

23:29 danneu: can anyone provide a db-spec string/map example they're using to connect to their heroku postgres db remotely (i.e. from their laptop)? been at it for an hour with no success

23:29 deathknight: (cheshire :) )

23:29 Jaood: my issue with LT is that it doesn't run in the terminal :P

23:31 ddellacosta: danneu: this used to work for me, no promises as I haven't used heroku lately: https://www.refheap.com/06d7b4600d81d539106b29669

23:32 danneu: ah, sorry, you said remotely from laptop?

23:33 danneu: like in your repl?

23:36 hellofunk: ddellacosta what would be the clojurescript equiv of this JS: var client=new ClientMsg({"logon": toLogon}); -- can it be done in a single line?

23:36 danneu: ddellacosta: yeah. i'm on a scavenger hunt to find the magical incantation. i've tried things like merging in {:ssl true, :sslfactory "org.postgresql.ssl.NonValidatingFactory"} from old stackoverflow answers, but no luck

23:37 ddellacosta: hellofunk: (let [client (ClientMsg #js {:logon toLogon})] ...) I guess?

23:37 danneu: hmm, well, maybe that article at the link in my example could help, and maybe there are some clues in there, but that is for connecting to the db on heroku, sorry. :-(

23:37 hellofunk: ddellacosta would you need a dot, ClientMsg. since it is a "new" JS form? My JS is quite bad to be honest

23:37 ddellacosta: hellofunk: sorry, should probably be ClientMsg.

23:37 yeah

23:38 hellofunk: cool thanks

23:45 deathknight: holy crap, it's the ddellacosta *_*

23:46 did you write the friend-oauth2 examples? I can't remember what project I saw your name attached to

23:47 hellofunk: ddellacosta do you ever get to a point where the browser just shows exceptions on the ring server and without changing code, restarting the browser resolves them? has started happening to me recently, rather odd. no need to restart the Ring server, just the browser.

23:47 danneu: ddellacosta: finally gathered all the pieces https://gist.github.com/danneu/c3d1b15d0b977ee3a154

23:47 ddellacosta: deathknight: yes, I wrote that. I really have to update that, got some outstanding pull requests. :-(

23:47 deathknight: I just emailed you about the issue/4! and I figured it out! woohoo

23:47 (yesterday, I believe)

23:47 ddellacosta: hellofunk: can't say I have seen that...sounds quite strange

23:47 deathknight: excellent. :-)

23:48 deathknight: what's your preferred HTTP client?

23:48 I'm using http.async.client and I'm failing at making a POST to google calender

23:48 ddellacosta: deathknight: I don't know that I've tried that, I've only used clj-http I believe

23:49 danneu: so, does that db-spec work when you use say, clojure.java.jdbc to connect?

23:49 deathknight: are you Harry?

23:49 deathknight: Henry :)

23:50 ddellacosta: deathknight: ah, okay! sorry I didn't respond sooner, but glad you got it worked out. :-)

23:50 deathknight: tis all gravy

23:50 ddellacosta: deathknight: sorry for screwing up your name too...haha

23:50 deathknight: now it's brimstone

23:51 ddellacosta: deathknight: you are very dark, with your deathknight and brimstone. Kind of a different vibe than Henry. ;-)

23:51 danneu: ddellacosta: yeah, i use clojure.java.jdbc directly - https://gist.github.com/danneu/c3d1b15d0b977ee3a154

23:52 ddellacosta: danneu: gotcha, so you can basically run migrations locally for your remote heroku db? I never thought of that but that would have solved a lot of problems I had in the past. Very nice.

23:53 danneu: ddellacosta: the real reason is that i like to develop straight against my remote dev server.

23:53 loliveira: resolved adding thre folowing dependency: [com.google.guava/guava "17.0"]

23:53 deathknight: ddellacosta: it would cool the embers in my soul if you could try to convert this to clj-http's version of a POST request: http://pastebin.com/5mRwMFwX

23:54 ddellacosta: deathknight: well, I think it's pretty straightforward--have you checked out the docs here? https://github.com/dakrone/clj-http#usage

23:55 deathknight: if you give that a shot and have trouble I'm happy to help, but I'll make you do the initial work. ;-)

23:55 deathknight: :)

23:55 that is a smile of vengeance

23:55 ddellacosta: hahaha

23:55 deathknight: I'm going to take you up on that offer

23:55 ddellacosta: deathknight: alright, sounds like a plan.

23:55 deathknight: :)

Logging service provided by n01se.net