2014-10-29
| 00:00 | justin_smith | numberten: oh, agent uses nprocessors+2 as well |
| 00:00 | numberten | magic number I guess |
| 00:00 | bbloom | puredanger: are you saying you can always use two more threads? |
| 00:00 | bbloom | heh |
| 00:00 | puredanger | exactly |
| 00:00 | justin_smith | numberten: it's core.async that multiplies by two and then adds 42 https://github.com/clojure/core.async/blob/aefbe7ad7e68f89f2ca584cd2fcd1bdf6fe8a601/src/main/clojure/clojure/core/async/impl/exec/threadpool.clj |
| 00:01 | justin_smith | I was misremembering |
| 00:01 | numberten | that's also weird.. |
| 00:01 | clojurebot | Titim gan éirí ort. |
| 00:01 | justin_smith | ~that |
| 00:01 | clojurebot | that is not the forget syntax |
| 00:01 | justin_smith | how meta, clojurebot |
| 00:02 | numberten | what does ~ do for clojurebot? |
| 00:02 | joshhead | *2 then +42? that seems pretty arbitrary |
| 00:02 | justin_smith | numberten: it asks him for a factoid |
| 00:02 | justin_smith | ~factoid |
| 00:02 | clojurebot | Excuse me? |
| 00:02 | numberten | ~justin_smith |
| 00:02 | justin_smith | ~botsnack |
| 00:02 | clojurebot | justin_smith is sits on a throne of lies |
| 00:02 | clojurebot | Thanks! Can I have chocolate next time |
| 00:03 | numberten | heh |
| 00:03 | justin_smith | numberten: a youthful indescretion preserved for all time, or until the sqlite db holding the factoids gets wiped |
| 00:03 | TEttinger | ~ask |
| 00:03 | clojurebot | The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question. |
| 00:04 | justin_smith | bodie_: https://github.com/swannodette/om/wiki/Cursors is the doc I found |
| 00:14 | bbloom | justin_smith: i think i'm going to abuse Rhino, since it has a js parser and code generator... although it's private impl details i may have to hack around to get at |
| 00:26 | justin_smith | bbloom: interesting |
| 00:27 | justin_smith | what's the default equality method that #{} uses? |
| 00:27 | justin_smith | it seems not to be .equals |
| 00:27 | justin_smith | ,(deftype Tuple [a b] Object (equals [this other] (and (= (.a this) (.a other)) (= (.b this) (.b other)))) (toString [this] (str "<" (.a this) "," (.b this) ">"))) |
| 00:27 | clojurebot | sandbox.Tuple |
| 00:28 | justin_smith | ,(into #{} [(Tuple. 0 0) (Tuple. 0 0) (Tuple. 0 0)]) |
| 00:28 | clojurebot | #{#<Tuple <0,0>> #<Tuple <0,0>> #<Tuple <0,0>>} |
| 00:28 | justin_smith | ,(apply = [(Tuple. 0 0) (Tuple. 0 0) (Tuple. 0 0)]) |
| 00:28 | clojurebot | true |
| 00:28 | justin_smith | I implemented equals, = returns true, but a set doesn't consider them unique |
| 00:29 | justin_smith | *identical |
| 00:38 | amalloy | justin_smith: you didn't implement hashCode |
| 00:38 | justin_smith | amalloy: yeah I figured it out http://stackoverflow.com/questions/26622511/clojure-value-equality-and-sets/26622863#26622863 |
| 01:48 | Balveda | Say I've got a map like so |
| 01:48 | Balveda | {:names [{:surn "A" :givn "B"} ... {:surn "X" :givn "Y"}]} |
| 01:50 | justin_smith | OK |
| 01:52 | egghead | very nice Balveda |
| 01:52 | Balveda-2 | huh, I cut out |
| 01:52 | egghead | :) |
| 01:52 | Balveda | Anyways, yeah |
| 01:53 | Balveda | I've been having some issues with a function because of that for a week or so and through some debugging I found out that what is wrong is that I'm doing (map-indexed list x-map) and that just gives me one item with everything in it |
| 01:54 | justin_smith | Balveda: I think I did not see the "because of that" you refer to |
| 01:54 | nathan7 | 06:47:50 < Balveda> {:names [{:surn "A" :givn "B"} ... {:surn "X" :givn "Y"}]} |
| 01:54 | nathan7 | that's all we got |
| 01:54 | Balveda | AH |
| 01:54 | Balveda | <Balveda> I want map-indexed to get me 0 {:surn "A" :givn "B"} 1 {:surn "C" :givn "D"} etc |
| 01:54 | Balveda | <Balveda> What fn could I feed it? |
| 01:54 | Balveda | Then everything else |
| 01:55 | Balveda | My connection's being pretty terrible today unfortunately |
| 01:55 | egghead | Balveda: i think you're looking for update-in ? |
| 01:55 | justin_smith | ,(map-indexed list (:names {:names [{:surn "A" :givn "B"} {:surn "X" :givn "Y"}]})) |
| 01:55 | clojurebot | ((0 {:surn "A", :givn "B"}) (1 {:surn "X", :givn "Y"})) |
| 01:55 | Balveda | hm.. |
| 01:57 | Balveda-2 | I'm actually doing something like that but it's not quite doing this |
| 02:01 | Balveda | jeez |
| 02:01 | Balveda | anyways |
| 02:01 | Balveda | I saw your code, justin_smith, and I am actually doing something like that |
| 02:01 | Balveda | It's all in cljs, Hoplon in particular |
| 02:01 | justin_smith | OK |
| 02:02 | Balveda | but the functionality should be similar |
| 02:02 | justin_smith | right, all of that above should just work in cljs |
| 02:09 | vIkSiT | hello all |
| 02:09 | vIkSiT | I have a fn that takes a few args : (myfn a b c :k v :k2 v2 ... ) |
| 02:10 | vIkSiT | in general, the v can be another complex structure |
| 02:10 | vIkSiT | eg |
| 02:10 | vIkSiT | :k {ns2/myfn {:k' :v' ... }) |
| 02:10 | vIkSiT | Id like to create a macro that allows me to return the args portion that are key/vals |
| 02:10 | vIkSiT | so |
| 02:10 | vIkSiT | (myfn a b c (mymacro)) |
| 02:10 | vIkSiT | should give me |
| 02:11 | vIkSiT | (myfn a b c :k v :k1 v1 ...) |
| 02:11 | vIkSiT | how would I do this? |
| 02:11 | vIkSiT | As you might imagine, these key values need to be constructed piecemeal based on input and i'd like to abstract it out from myfn |
| 02:11 | vIkSiT | ideas? |
| 02:12 | justin_smith | are all of those instances of myfn the same function? |
| 02:12 | vIkSiT | oh sorry no |
| 02:12 | vIkSiT | that should be (ns2/anotherfn) |
| 02:13 | vIkSiT | I guess what I can't figure out is - what should be the return type of this macro/function that returns these kv pairs? |
| 02:13 | justin_smith | vIkSiT: macros cannot transform an outer form |
| 02:13 | justin_smith | they only transform what is inside them |
| 02:13 | justin_smith | not what wraps them |
| 02:13 | vIkSiT | right |
| 02:14 | vIkSiT | I guess my question is more on - if I have to call (myfn a b c & args) |
| 02:14 | vIkSiT | how do I get these args from some function |
| 02:14 | justin_smith | apply |
| 02:14 | vIkSiT | hmm |
| 02:15 | vIkSiT | what's a good example? |
| 02:15 | vIkSiT | (defn myfn [a b c & args] |
| 02:15 | vIkSiT | (prn a b c args)) |
| 02:16 | vIkSiT | (myfn 1 2 3 :k1 'v1 :k2 'v2) -> 1 2 3 (:k1 v1 :k2 v2) |
| 02:16 | justin_smith | ,(apply (fn [& {:keys [a b c]}] [c b a]) (apply concat {:a 0 :b 1 :c 2})) |
| 02:16 | clojurebot | [2 1 0] |
| 02:16 | justin_smith | the extra apply concat is because & {:keys ...} sucks |
| 02:16 | vIkSiT | sorry whats going on here again? |
| 02:17 | justin_smith | ,(def args{:a 0 :b 1 :c 2}) |
| 02:17 | clojurebot | #'sandbox/args |
| 02:17 | justin_smith | ,(defn dothing [& {:keys [a b c]}] [c b a]) |
| 02:17 | clojurebot | #'sandbox/dothing |
| 02:17 | justin_smith | ,(apply dothing (apply concat args)) |
| 02:17 | clojurebot | [2 1 0] |
| 02:17 | vIkSiT | ah hmm |
| 02:18 | justin_smith | or you could just not use & {:keys ...}, and everything is suddenly much simpler |
| 02:19 | vIkSiT | sadly its not my function. library |
| 02:19 | justin_smith | vIkSiT: the apply concat is needed to put the map in the shape that & {:keys ...} needs |
| 02:20 | vIkSiT | justin_smith, trying to wrap my head |
| 02:21 | vIkSiT | so what happens when dothing has [a b c & args] |
| 02:21 | vIkSiT | how would I use it? |
| 02:21 | justin_smith | (apply dothing a b c (apply concat args)) |
| 02:21 | justin_smith | (if args is a map) |
| 02:21 | justin_smith | ,(apply + 1 2 3 [4 5 ]) |
| 02:21 | clojurebot | 15 |
| 02:22 | justin_smith | only the last arg is unwrapped, the rest are used as normal |
| 02:23 | vIkSiT | hmm |
| 02:29 | vIkSiT | justin_smith - one issue here |
| 02:29 | vIkSiT | (apply concat mymap) |
| 02:29 | vIkSiT | gives (:k1 v k2 v...) |
| 02:29 | vIkSiT | its a list |
| 02:29 | vIkSiT | whereas what I want is the values themselves |
| 02:29 | justin_smith | just the values? |
| 02:30 | vIkSiT | ,(defn myfn [a b c & args] |
| 02:30 | vIkSiT | (prn a b c args)) |
| 02:30 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 02:30 | justin_smith | use vals then |
| 02:30 | vIkSiT | sorry I mean |
| 02:30 | vIkSiT | (apply myfn 1 2 3 (flatten (apply concat {:k1 1 :k2 3}))) |
| 02:30 | vIkSiT | 1 2 3 (:k1 1 :k2 3) |
| 02:30 | justin_smith | ,(vals {:a 0 :b 1 :c 2 :d 4}) |
| 02:30 | clojurebot | (2 1 4 0) |
| 02:30 | vIkSiT | but I want |
| 02:30 | justin_smith | you don't need flatten |
| 02:30 | vIkSiT | 1 2 3 :k1 1 :k2 3 |
| 02:31 | justin_smith | vIkSiT: that is the point of apply |
| 02:31 | justin_smith | vIkSiT: you can't alter the args to myfn inside one of its args, that's just not a thing |
| 02:31 | clojurebot | I don't understand. |
| 02:31 | justin_smith | so you use apply |
| 02:31 | vIkSiT | hmm |
| 02:32 | justin_smith | there is no way to wrap your map such that it alters the arg list - but apply will construct a new arg list |
| 02:32 | justin_smith | and also, that flatten is not needed, and can break things |
| 02:32 | justin_smith | ~flatten |
| 02:32 | clojurebot | flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with. |
| 02:32 | justin_smith | I've never actually ever needed flatten |
| 02:35 | justin_smith | vIkSiT: is the issue you are describing with myfn that you want myfn to make a single collection of all its args? |
| 02:35 | vIkSiT | i'm just wrapping my head around how this apply is working with the concat map |
| 02:35 | vIkSiT | hmm |
| 02:35 | justin_smith | (defn otherfn [a b c & args] (println (conj args c b a))) |
| 02:35 | justin_smith | ,(defn otherfn [a b c & args] (println (conj args c b a))) |
| 02:35 | clojurebot | #'sandbox/otherfn |
| 02:36 | justin_smith | ,(apply otherfn 1 2 3 [4 5 6]) |
| 02:36 | clojurebot | (1 2 3 4 5 ...)\n |
| 02:36 | justin_smith | ,(defn otherfn [a b c & args] (apply println (conj args c b a))) |
| 02:36 | clojurebot | #'sandbox/otherfn |
| 02:36 | justin_smith | ,(apply otherfn 1 2 3 [4 5 6]) |
| 02:36 | clojurebot | 1 2 3 4 5 6\n |
| 02:36 | vIkSiT | aah |
| 02:36 | vIkSiT | got it |
| 02:37 | vIkSiT | thanks justin_smith - that was super helpful :) |
| 02:37 | justin_smith | these also work: |
| 02:37 | vIkSiT | hmm? |
| 02:37 | justin_smith | ,(otherfn 1 2 3 4 5 6) |
| 02:37 | clojurebot | 1 2 3 4 5 6\n |
| 02:37 | vIkSiT | ah |
| 02:37 | vIkSiT | yes |
| 02:37 | vIkSiT | I understand how apply works now |
| 02:38 | justin_smith | ,(apply otherfn [1 2 3 4 5 6]) |
| 02:38 | clojurebot | 1 2 3 4 5 6\n |
| 02:38 | justin_smith | ,(apply otherfn 1 [2 3 4 5 6]) |
| 02:38 | clojurebot | 1 2 3 4 5 6\n |
| 02:38 | justin_smith | etc. etc. |
| 02:38 | vIkSiT | ah |
| 02:39 | vIkSiT | makes sense |
| 02:40 | zRecursive | ,(doc ->) |
| 02:40 | clojurebot | "([x & forms]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc." |
| 02:41 | justin_smith | zRecursive: something that really helps with -> is using macroexpand |
| 02:42 | zRecursive | ,(macroexpand ->) |
| 02:42 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->, compiling:(NO_SOURCE_PATH:0:0)> |
| 02:42 | justin_smith | ,(macroexpand '(-> 1 inc (println "is the number"))) |
| 02:42 | clojurebot | (println (inc 1) "is the number") |
| 02:42 | vIkSiT | oh nice trick |
| 02:42 | zRecursive | great! |
| 02:47 | justin_smith | anyway, I'm staying logged in but turning in for the night, see you all later |
| 02:48 | Balveda-2 | (inc justin_smith) |
| 02:48 | lazybot | ⇒ 107 |
| 02:49 | fairuz | (+ 1 2) |
| 02:49 | clojurebot | 3 |
| 03:16 | rurumate | Is defrecord "discouraged"? |
| 03:20 | arrdem | rurumate: in what sense? |
| 03:20 | arrdem | rurumate: defrecord and deftype are not tools one typically reaches for right away if that's what you mean |
| 03:20 | arrdem | rurumate: but they are working tools to be used when appropriate |
| 03:25 | rurumate | arrdem: The reader can not read records. When performance is not critical, should hash maps always be preferred? Records are also often used with protocols. Is it preferable to use defmulti / defmethod, and a dispatch field in hash maps instead? I'm looking for the best practice way here. |
| 03:28 | arrdem | rurumate: maps represent arbitrary mappings... for small symbolic mapings records or types are intended to do better |
| 03:28 | arrdem | rurumate: the "best practice" is to prototype everything with plain maps, get that working and then use records if there is a gain from doing so |
| 03:29 | rurumate | Also, what happens when you have a record based protocol, and then use standard functions like assoc on your records. That can have unexpected results, because it converts the record to a map, and then the the correct dispatch of the prototype may not trigger. It seems that this can lead to subtle bugs and brittle code |
| 03:30 | arrdem | rurumate: no records are maps and remain records if you assoc or dissoc on them |
| 03:30 | rurumate | *dispatch of the protocol may not trigger |
| 03:30 | arrdem | if you merge on a record you can discard the record class and get a map back, but that's sketchy anway |
| 03:33 | rurumate | I think records are mostly awkward to work with |
| 03:33 | rurumate | more awkward than regular maps, anyway |
| 03:33 | arrdem | that's definitely true |
| 03:34 | arrdem | but maps are a less complex tool and are generally preferred so you shouldn't be surprised. |
| 03:35 | yekKhaste | Hi |
| 03:35 | yekKhaste | Is clojure good for rapid web development? |
| 03:36 | yekKhaste | Clojure can compare to something link rails for rapid web development? |
| 03:39 | rurumate | yekKhaste: it's a lisp, so it should be good for pretty much anything |
| 03:39 | yekKhaste | rurumate, Has it any full stack web framework that can compare to rails? |
| 03:39 | arrdem | yekKhaste: no |
| 03:39 | rurumate | there are some web frameworks, but I'm no authority on that. I doubt it has something as mature as rails |
| 03:40 | arrdem | rurumate: maturity I would debate, we certainly have no monolitic web platform ala rails |
| 03:40 | rurumate | it's what I meant to say |
| 03:41 | yekKhaste | And do you recommended clojure for freelancer developers? |
| 03:41 | arrdem | I have freelanced with Clojure successfully before... |
| 03:41 | arrdem | many Clojure shops are contractors |
| 03:41 | rurumate | if you sell the source code to the client, better ask them if they want to maintain that |
| 03:42 | yekKhaste | Actual I am looking for some modern tool for rapid backend development |
| 03:43 | yekKhaste | I what too know cant I use clojure or not |
| 03:44 | arrdem | I don't think there's any way we can reasonably make that assessment for you |
| 03:44 | arrdem | I've used Clojure to build websites and contract as have others... |
| 03:44 | arrdem | it can be done |
| 03:44 | arrdem | whether it's appropriate for you... who knows |
| 03:44 | yekKhaste | arrdem, Thanks alot |
| 03:45 | arrdem | yekKhaste: sorry, that's the most helpfull answer I can give :/ |
| 04:16 | sm0ke | ,(def a (atom (proxy [Object] [] (finalize [] (println "OK gcd.."))))) |
| 04:16 | clojurebot | #'sandbox/a |
| 04:16 | sm0ke | ,(reset! a nil) |
| 04:16 | clojurebot | nil |
| 04:16 | sm0ke | ,(System/gc) |
| 04:16 | clojurebot | nil |
| 04:16 | sm0ke | can someone tell why it is not gc'd |
| 04:17 | hyPiRion | sm0ke: you'd probably need to run the gc 4-5 times |
| 04:18 | sm0ke | ran it 40 time |
| 04:18 | sm0ke | nothing |
| 04:18 | hyPiRion | hm |
| 04:19 | sm0ke | ,(repeatedly #(System/gc)) |
| 04:19 | clojurebot | (nil nil nil nil nil ...) |
| 04:19 | sm0ke | no helo |
| 04:19 | sm0ke | no help either |
| 04:20 | opqdonut | sm0ke: a) there's no guarantee on running finalizers timely b) even if the finalizer was run, clojurebot might not print the line |
| 04:20 | sm0ke | opqdonut: i obviously was testing this on my machine! |
| 04:20 | opqdonut | that's what I thought :) |
| 04:21 | hyPiRion | well. The JVM doesn't guarantee that finalize is called on an object, so. |
| 04:23 | yocapybara | guys I'm being a dufus. Say I'm (/ 4 3) dividing 4 by 3, and I want to get 2 so to round up to nearest integer, I can't use quot as that rounds down, anything easy out of the box? or do I have to bring in BigDecimal? |
| 04:23 | sm0ke | wow, so i need to create a Java class to prove this now |
| 04:24 | pyrtsa | sm0ke: As nice as it would be, finalisers are not the way to deal with automatic cleanup of non-memory resources in Clojure. |
| 04:24 | pyrtsa | ,(with-open [_ (reify java.lang.AutoCloseable (close [_] (println "closed")))] (println "working on it...")) |
| 04:24 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: java.lang.AutoCloseable, compiling:(NO_SOURCE_FILE:0:0)> |
| 04:24 | pyrtsa | Doh. |
| 04:24 | pyrtsa | ,(with-open [_ (reify java.io.Closeable (close [_] (println "closed")))] (println "working on it...")) |
| 04:24 | clojurebot | working on it...\nclosed\n |
| 04:25 | sm0ke | pyrtsa: i have a kind of situation where i cannot use with-open |
| 04:25 | pyrtsa | Macros (e.g. with-open) could be a way around it, though. |
| 04:25 | pyrtsa | Elaborate? |
| 04:25 | opqdonut | ,(let [obj (proxy [Object] [] (finalize [] (println "OK gcd..")))] (.finalize obj)) |
| 04:25 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: finalize for class sandbox.proxy$java.lang.Object$ff19274a> |
| 04:25 | amalloy | sm0ke: *out* is not bound to anything while you're running a finalizer |
| 04:25 | opqdonut | ^ that's fishy |
| 04:25 | opqdonut | amalloy: ah of course |
| 04:25 | opqdonut | run by the finalizer thread |
| 04:25 | pyrtsa | amalloy: Wow, didn't know! |
| 04:26 | pyrtsa | (inc amalloy) |
| 04:26 | lazybot | ⇒ 181 |
| 04:26 | sm0ke | ok then |
| 04:26 | hyPiRion | yocapybara: (defn div-up [a b] (quot (+ a b -1) b)) |
| 04:26 | sm0ke | ,(def b (atom 1)) |
| 04:26 | clojurebot | #'sandbox/b |
| 04:26 | sm0ke | ,(def a (atom (proxy [Object] [] (finalize [] (swap! b inc))))) |
| 04:26 | clojurebot | #'sandbox/a |
| 04:26 | hyPiRion | amalloy: I tried setting an atom. No response there either. |
| 04:26 | sm0ke | ,(reset! a nil) |
| 04:26 | clojurebot | nil |
| 04:27 | sm0ke | ,(repeatedly 100 #(System/gc)) |
| 04:27 | clojurebot | (nil nil nil nil nil ...) |
| 04:27 | sm0ke | ,@b |
| 04:27 | clojurebot | 1 |
| 04:27 | amalloy | opqdonut: i doubt if you're allowed to call finalize yourself. it's a protected method |
| 04:27 | sm0ke | well |
| 04:27 | sm0ke | ,(repeatedly 100 #(System/gc)) |
| 04:27 | clojurebot | (nil nil nil nil nil ...) |
| 04:27 | sm0ke | ,@b |
| 04:27 | clojurebot | 1 |
| 04:28 | yocapybara | hyPiRion: that is intruiging, feel like my mind is turning to mush as I get older! - thanks, going to play in a repl |
| 04:29 | yocapybara | man I totally would have never have come up with that, I need to go back to junior high and retake math classes |
| 04:29 | sm0ke | ,(repeatedly 100 #(System/gc)) |
| 04:29 | clojurebot | (nil nil nil nil nil ...) |
| 04:29 | sm0ke | ,@b |
| 04:29 | clojurebot | 1 |
| 04:30 | sm0ke | i am going to keep doing this unless java gives up...you stuPUID JAAVvaaaVAa |
| 04:30 | amalloy | sm0ke: do it in your own repl. nobody needs to see that pasted here over and over |
| 04:30 | sm0ke | :) |
| 04:31 | sm0ke | i think its a problem with proxy |
| 04:31 | amalloy | also, like...who cares? finalizers are a disastrous antipattern; no correct program can rely on finalizers ever being run: http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx |
| 04:31 | amalloy | it's a curiosity, of course, and i'd like to know why this isn't working here |
| 04:32 | amalloy | but cursing java seems like the wrong approach: any resolution you get here isn't really going to help you write a better program, as much as taking some other approach would help |
| 04:33 | hyPiRion | yocapybara: np – It's probably because I've tried to do round up integer divisions in the past :) |
| 04:33 | yocapybara | hyPiRion: I'm doing it in excel on loads of numbers to try to figure out what sorcery it is, man to think I used to do pages and pages of math in school :) |
| 04:34 | hyPiRion | It's not entirely foolproof though. I think I'd only use it for positive numbers. |
| 04:35 | yocapybara | hyPiRion: that's the context in which I'm using it so that's great |
| 04:37 | ro_st | using logback, i'd like to put everything in our code in one file, except for a couple namespaces, which i'd like to log to a different file. does anyone perhaps have an example logback.xml with this situation? |
| 04:38 | hyPiRion | yocapybara: Another way to write it is (+ 1 (quot (- a 1) b)) if that helps your understanding better. |
| 04:38 | hyPiRion | I think it should be easier to "see" why that one works |
| 04:41 | yocapybara | hyPiRion: thanks :) will put that alongside, yes I think I can already see that one more |
| 05:19 | justin_smith | rurumate: the reader can read records |
| 05:30 | justin_smith | ,(defrecord Foo [x y]) |
| 05:30 | clojurebot | sandbox.Foo |
| 05:30 | justin_smith | ,(Foo. 0 1) |
| 05:30 | clojurebot | #sandbox.Foo{:x 0, :y 1} |
| 05:30 | justin_smith | ,(= #sandbox.Foo{:x 0 :y 1} (Foo. 0 1)) |
| 05:30 | clojurebot | #<RuntimeException java.lang.RuntimeException: Record construction syntax can only be used when *read-eval* == true> |
| 05:30 | justin_smith | bleh |
| 05:31 | justin_smith | anyway, it can be read |
| 05:31 | justin_smith | (require '[clojure.edn :as edn]) |
| 05:31 | justin_smith | ,(require '[clojure.edn :as edn]) |
| 05:31 | clojurebot | nil |
| 05:32 | justin_smith | ,(edn/read-string "#sandbox.Foo{:x 0 :y 1}") |
| 05:32 | clojurebot | #<RuntimeException java.lang.RuntimeException: No reader function for tag sandbox.Foo> |
| 05:38 | justin_smith | rurumate: this stuff doesn't work with clojurebot, but it all works in a standard clojure process / project, including reader literals in files |
| 05:40 | rurumate | justin_smith: thanks |
| 05:41 | danners | hey what is the best free tutorial for clojure, assuming no previous functional expericence ? |
| 05:42 | scottj | danners: braveclojure.com is the most popular one recently |
| 05:44 | danners | scottj: thanks |
| 05:49 | dysfun | hi all. i'm building a securitymanager that prevents user-provided code from being naughty. where naughty is largely defined as "can open files, use the network, generally perform I/O". obviously i can only lock on a class level. is there any wider mechanism for banning those operations? |
| 05:50 | sm0ke | dysfun: best would be to sandbox the process imo |
| 05:51 | sm0ke | or you can take a look at ##(File. "ssss") |
| 05:51 | lazybot | java.lang.IllegalArgumentException: Unable to resolve classname: File |
| 05:51 | sm0ke | ,(java.util.File. "aaa") |
| 05:51 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: java.util.File, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:52 | sm0ke | wowsad |
| 05:52 | sm0ke | ,(java.io.File. "aaa") |
| 05:52 | clojurebot | #<File aaa> |
| 05:52 | sm0ke | hurmm oh |
| 05:53 | dysfun | exactly |
| 05:53 | dysfun | and let's not forget java.nio.* either |
| 05:54 | sm0ke | well File is just logical unless you do some operations further |
| 05:54 | sm0ke | ,(slurp "/etc/hosts") |
| 05:54 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 05:54 | sm0ke | see |
| 05:55 | dysfun | yes, but how much is that restricted? can i for example check the existence of a file or read the contents of a directory? |
| 05:57 | dysfun | and where is the source for the bot's sandbox? |
| 05:59 | justin_smith | both clojurebot and lazybot are on github |
| 05:59 | dysfun | whose account? |
| 05:59 | justin_smith | $google github lazybot clojure |
| 05:59 | lazybot | [Raynes/lazybot · GitHub] https://github.com/Raynes/lazybot |
| 05:59 | justin_smith | $google github clojurebot |
| 05:59 | lazybot | [hiredman/clojurebot · GitHub] https://github.com/hiredman/clojurebot |
| 06:00 | dysfun | sweet |
| 06:09 | hugod | bbloom: stevedore was originally based on https://github.com/arohner/scriptjure |
| 08:29 | jonathanj | is there really no shorter way of writing (assoc xs (dec (count xs)) (str ":" (peek xs)))? |
| 08:29 | jonathanj | having to repeat "xs" three times seems crazy |
| 08:30 | clgv | jonathanj: time to write a function ^^ |
| 08:30 | clgv | jonathanj: create a my-project.tools namespace and put that helper function there |
| 08:32 | clgv | jonathanj: e.g. (defn update-last [xs f & args] (apply update-in xs [(dec (count xs))] f args)) usable as (update-last [0 1 2] #(str ":" %)) |
| 08:33 | clgv | ,(defn update-last [xs f & args] (apply update-in xs [(dec (count xs))] f args)) |
| 08:33 | clojurebot | #'sandbox/update-last |
| 08:33 | clgv | ,(update-last [0 1 2] #(str ":" %)) |
| 08:33 | clojurebot | [0 1 ":2"] |
| 08:41 | clgv | what is the recommended setup for tagged literals? such that they are usable in repl as well as in a standalone uberjar? |
| 08:53 | dysfun | the clojurebot sandbox. is the reason that it gets the parent of clojure.lang.RT's classloader so that it can load another version of clojure/ |
| 08:55 | dysfun | sorry, not the clojurebot sandbox, classlojure |
| 08:57 | clgv | dysfun: what is the context question? |
| 08:57 | clgv | did they fix the memory leaks in classlojure yet? |
| 08:58 | dysfun | i have no idea. i haven't used classlojure before |
| 08:58 | clgv | humm 1 year no change - so I guess not |
| 08:58 | dysfun | the problem i'm trying to solve is loading plugins written in approximately any jvm language |
| 08:58 | dysfun | classlojure's code looks relatively straightforward to sort the classloader/only-load-from-this-jar problem |
| 08:58 | dysfun | the securitymanager, well, that's going to be tedious, i have no doubt |
| 08:59 | dysfun | however, i'm curious why they're doing a .getParent on clojure.lang.RT's classloader. the only reason i can think they would is because they explicitly advertise loading other versions of clojure |
| 08:59 | clgv | dysfun: there is clojail for the security stuff. it includes functions to configure jvm security mechanisms as well |
| 09:00 | dysfun | yes, i'm aware of clojail, but it seems targeted mostly at securing clojure, so we'll see how that one pans out |
| 09:00 | clgv | yeah but that includes the usual jvm stuff, afair |
| 09:00 | dysfun | *nod*. as i say, we'll see how it pans out |
| 09:01 | dysfun | if i can reuse it, of course i'm thrilled to not have to do the tedious stuff |
| 09:01 | clgv | I think it's mostly specifying white lists of what is allowed |
| 09:03 | clgv | dysfun: be aware that you can only spin up a small number of classlojure classloaders due to memory leaks, when you use classlojure |
| 09:03 | clgv | dysfun: I tried that a while back |
| 09:03 | dysfun | i am not using classlojure |
| 09:03 | clgv | ok ^^ |
| 09:04 | dysfun | mostly because the actual part that i need is several lines of code |
| 09:04 | clgv | applies when loading custom clojure version in any classloader as well |
| 09:04 | dysfun | i don't intend to support that model. at least not just yet |
| 09:04 | clgv | at least for versions before 1.6 |
| 09:04 | dysfun | i'll probably support loading 1.6 when 1.6.1 comes out |
| 09:04 | dysfun | but i can't see it actually breaking anything |
| 09:05 | clgv | huh? 1.7 will be next ;) |
| 09:05 | dysfun | oh |
| 09:05 | dysfun | in any case, i certainly have no intention of supporting clojure < 1.6 |
| 09:06 | dysfun | i expect most of the plugins i'm loading will be java anyway |
| 09:38 | nicola | Hi, how to wrap InputStream into async channel? |
| 09:42 | ohpauleez | nicola: In the labs namespace, there's a function called `spool`that puts a sequence onto a channel |
| 09:42 | ohpauleez | you can get a sequence from the inputstream and spool it onto the channel: https://clojure.github.io/core.async/#clojure.core.async.lab/spool |
| 09:43 | ohpauleez | If you want to push an inputstream directly onto a channel without the extra allocations, you'll need to implement a new input stream that is passed the channel in the constructor |
| 09:45 | ApeShot | So I am having a very mysterious error in a clojure project: lein compile has suddenly started failing with a null pointer exception and all it tells me is that it is on core.clj:1 |
| 09:45 | ApeShot | No information about which core (of which there are many) |
| 09:45 | teslanick | Does onto-chan not work with seqs? |
| 09:45 | ApeShot | How can I cajole lein into compiling one file at a time |
| 09:45 | ApeShot | Or get it to give me more verbose output |
| 09:47 | nicola | @ohpauleez thx |
| 09:48 | ohpauleez | nicola: teslanick: Good question - It should. spool can consume a lazy seq though (iirc), without realizing the entire seq |
| 09:48 | clgv | ApeShot: do you have a :main namespace? |
| 09:48 | nicola | @ohpauleez i want run long shell command and >! progress into channel |
| 09:49 | teslanick | ohpauleez: I hadn't thought of putting an infinite seq on a channel, but I can see why that would be useful. |
| 09:49 | ApeShot | Maybe I accidentally deleted it? |
| 09:49 | ApeShot | It is a play-clj template |
| 09:49 | ApeShot | So there is some magic I don't get |
| 09:50 | ApeShot | But i've been working and building the project successfully for quite some time |
| 09:51 | clgv | ApeShot: it is probably the core.clj in your project since you cant change those of the dependency libraries |
| 09:51 | ohpauleez | nicola: Yep, use `line-seq` and the io/reader. Then use spool with that seq and you should have what you're looking for |
| 09:54 | ApeShot | clgv: the play-clj template and usage doesn't have you define the main ns yourself |
| 09:55 | clgv | ApeShot: you didn't use a VCS by any chance? |
| 09:55 | the_danko | wow, just getting to macros in brave clojure! sweeet! |
| 09:56 | mikepence | oh, yeah |
| 09:56 | mikepence | hey, I am doing a presentation to our local Java UG tonight re: fp and clojure |
| 09:56 | mikepence | looking for some sample code to share, something public on github |
| 09:56 | mikepence | real-worldish |
| 09:56 | mikepence | not fib seq or other minimalist stuff |
| 09:57 | ApeShot | I hadn't yet put in a git repo |
| 09:57 | ApeShot | I know, stupid |
| 09:57 | clgv | ApeShot: then it would be a matter of a view minutes to find that error ;) |
| 09:57 | clgv | *few |
| 09:58 | ApeShot | clgv: That was the first thing I checked, and then remembered that I had been programming without a net |
| 09:58 | ApeShot | I have a back up that is a day old |
| 09:58 | ApeShot | Which still compiles |
| 09:58 | ApeShot | So I can laborously do ugly diggs |
| 09:58 | ApeShot | diffs |
| 09:59 | ApeShot | But I figured someone else might have an idea about how to target that search |
| 09:59 | ApeShot | Looking for the main ns might be the thing |
| 09:59 | clgv | ApeShot: you can use "meld" or similar to compare the whole project directories |
| 09:59 | ApeShot | I don't know how I could have messed it up |
| 09:59 | clgv | ApeShot: well not without seeing the code... |
| 10:02 | ApeShot | Ok, so my project.clj has a line : :main all-ghosts-vs-all-skeletons.core.desktop-launcher |
| 10:03 | ApeShot | And indeed this is the entry point of the project and it exists |
| 10:03 | japro | maybe that is a Halloween joke :o) |
| 10:04 | japro | oh wait, that is your project name i guess... nvm |
| 10:04 | clgv | ApeShot: on rethinking it that really does not matter, find the core.clj you wrote yourself |
| 10:05 | ApeShot | I have many |
| 10:05 | ApeShot | For different modules of the project |
| 10:05 | clgv | you have many core.clj in one project? O_o |
| 10:05 | stuartsierra | ApeShot: Comment out `:main`, do `lein clean`, start a REPL and `require` your namespaces one by one. |
| 10:05 | ApeShot | I know with each line my failure to use git makes me look dumb |
| 10:05 | CookedGryphon | What are people's opinions on side-effecting actions in transducers? |
| 10:05 | ApeShot | I'm sort of new to how people organize clojure projects, but mine has a variety slightly coupled components parts, each of which has a directory and a core |
| 10:06 | CookedGryphon | I'm re-writing a number of go-loops in my code to simply use transducers and pipes, which is fine for all the functional transformations that push on a different value down a different channel... but some of the go loops were listening to events and then acting as a result... |
| 10:06 | CookedGryphon | if I follow the pattern of converting to transducers, that means a side-effecting map |
| 10:07 | CookedGryphon | but leaving it as go-loops bugs me in other ways (not composable, etc) |
| 10:07 | TimMc | clgv: ++ for meld |
| 10:07 | clgv | TimMc: :D |
| 10:07 | clgv | if you can afford it, BeyondCompare is nice as well |
| 10:10 | stuartsierra | CookedGryphon: Transducers are evaluated "eagerly" so side-effects are generally less of a problem than they would be with lazy-seqs. |
| 10:14 | hyPiRion | stuartsierra: huh? I was under the impression that transducers doesn't enforce strictness nor laziness. Or perhaps that's why you wrote "eagerly". |
| 10:15 | CookedGryphon | stuartsierra: yeah, this was my quandry, I know that in this case it would work, but is it encouraged, or is there a better way to separate out the side effecty stuff... |
| 10:15 | stuartsierra | hyPiRion: Yeah, it depends on how you "consume" them. |
| 10:15 | rurumate | CookedGryphon: can you paste an example of how you're rewriting the go-loops using transducers? I'd like to see that thanks |
| 10:15 | stuartsierra | Like how I'm giving "advice" right now. |
| 10:15 | hyPiRion | right |
| 10:16 | CookedGryphon | or is it just a case of, I'm using it on a channel, I can expect it to process as it goes |
| 10:16 | CookedGryphon | sure, I'll try and pick a good example |
| 10:17 | stuartsierra | CookedGryphon: While I wouldn't necessarily say it's "wrong" to have a side-effect in a transduced process, I would be more inclined to try to isolate the side effects at the "end" of the process. |
| 10:18 | CookedGryphon | stuartsierra: indeed, and that's actually what's happening here |
| 10:18 | CookedGryphon | *but* I have an ulterior motive |
| 10:18 | stuartsierra | A side effecting fn can be passed to `run!` or used as the "sink" from a channel. |
| 10:18 | CookedGryphon | which is to reduce the number of namespaces depending on core.async macros, because it's a pain re-using the code in clojurescript |
| 10:19 | CookedGryphon | are you referring to a library fn run!, or is that a hypothetical fn I should write? |
| 10:19 | Bronsa | CookedGryphon: it's a new 1.7 function |
| 10:19 | Bronsa | ,(doc run!) |
| 10:20 | clojurebot | "([proc coll]); Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the collection. Returns nil" |
| 10:20 | CookedGryphon | will that work with core.async channels? |
| 10:20 | puredanger | if you do channel things in it, that should be fine |
| 10:21 | puredanger | it doesn't know anything specifically about channels |
| 10:22 | CookedGryphon | other way round, I'm talking about doing a side effecting function for things being outputted from a channel |
| 10:22 | CookedGryphon | I don't think run helps me here |
| 10:22 | puredanger | no, don't think so |
| 10:24 | puredanger | so I guess you can't use a thread if you want this to work in cljs too |
| 10:24 | puredanger | seems like a go loop is probably your best bet in that case? |
| 10:24 | CookedGryphon | so yeah, *without macros* (i.e. just using pipes, transducers and other composable channel operations), what's the nicest way of having a sink function |
| 10:25 | CookedGryphon | which just does a side effecting thing on each element as it comes out of the channel |
| 10:25 | puredanger | isn't that obvious to write in a go loop? |
| 10:25 | CookedGryphon | yeah, and I wrote it the obvious way first time around |
| 10:26 | CookedGryphon | now it's structurally bitten me as none of the go-loop code is re-usable, adding functionality bloats the go loops because they're not composable |
| 10:27 | CookedGryphon | but this may well be one case where it's reasonable to leave it as a go loop |
| 10:27 | puredanger | I would try to put as little code as possible in the go loop and just keep it to primarily doing channel things and control flow |
| 10:27 | CookedGryphon | yep, which is exactly what I did |
| 10:28 | CookedGryphon | and I ended up with 4 lines of boilerplate for everything I wanted to do with go-loops |
| 10:28 | CookedGryphon | now I've rewritten most of the take a thing from these pipes, combine and put out to that pipe |
| 10:28 | CookedGryphon | as transducers and pipe operations |
| 10:28 | CookedGryphon | and it's lovely and concise |
| 10:28 | CookedGryphon | and composable |
| 10:29 | CookedGryphon | and so I'm exploring other options for this end point which takes a side effecting action on each item coming out of the channel |
| 10:29 | CookedGryphon | to see if there's a similar gain to be made |
| 10:30 | CookedGryphon | this rewrite also means I have taken the core.async dependency out of a lot of namespaces entirely, they just produce a transducer |
| 10:30 | puredanger | there definitely is a missing "sink" operation in core.async - there's a ticket for this out there |
| 10:30 | CookedGryphon | and the fact that it goes via async channels is now a detail which the caller is responsible |
| 10:30 | CookedGryphon | cool, I'll have a look and upvote it if I find it |
| 10:31 | puredanger | http://dev.clojure.org/jira/browse/ASYNC-67 |
| 10:32 | CookedGryphon | Yeah, that |
| 10:32 | CookedGryphon | In fact, I might just take that into my code as a utility |
| 10:37 | stuartsierra | puredanger: thanks for that link |
| 10:40 | puredanger | we are trying to bring async tickets into the same review process we use for Clojure itself but that has been slow to take hold |
| 10:41 | Bronsa | puredanger: I thought the point of contribs was to have a faster contribution process than clojure? |
| 10:41 | puredanger | async is special |
| 10:42 | puredanger | but it can also have releases independent of Clojure |
| 10:42 | puredanger | and that's actually why it's hard to integrate - the reports are focused around a target release and those dimensions differ between core and async |
| 10:42 | puredanger | I'm still trying to decide exactly how to deal with that |
| 10:43 | puredanger | it's possible that some of async could move into core in the future. I'm not foretelling anything… just saying that's a possibility. |
| 10:44 | Bronsa | clojurebot: core.async |is| special |
| 10:44 | clojurebot | 'Sea, mhuise. |
| 10:44 | puredanger | my personal opinion is that async is important enough to be in the box. but I also think it's still changing enough that I'd like to be able to release separately and more frequently. just my opinion / not speaking for Rich or anything official. |
| 10:45 | Bronsa | puredanger: ok, thanks |
| 10:46 | ssa | can you not `import` in the body of a namespace? |
| 10:46 | Bronsa | sure you can ssa |
| 10:46 | Bronsa | ,Buffer |
| 10:46 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: Buffer in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 10:47 | Bronsa | ,(import 'java.nio.Buffer) |
| 10:47 | clojurebot | java.nio.Buffer |
| 10:47 | Bronsa | ,Buffer |
| 10:47 | clojurebot | java.nio.Buffer |
| 10:47 | Bronsa | ^ |
| 10:47 | ssa | cool, ok -- i am doing the following but am getting an exception: |
| 10:47 | ssa | (import 'org.apache.curator.retry.BoundedExponentialBackoffRetry) |
| 10:47 | ssa | (BoundedExponentialBackoffRetry. 100 120000 10) |
| 10:47 | Bronsa | ssa: what's the exception? |
| 10:47 | ssa | Unable to resolve classname: BoundedExponentialBackoffRetry |
| 10:48 | borkdude | object oriented programming: the blind leading the blind (haha, sorry, just wanted to rant) |
| 10:48 | Bronsa | ssa: is the import statement in the top-level? |
| 10:48 | ssa | also happens when i do (import [org.apache.curator.retry BoundedExponentialBackoffRetry]) |
| 10:48 | ssa | no |
| 10:48 | ssa | it's in a function |
| 10:48 | Bronsa | ssa: that's your issue |
| 10:48 | ssa | ah awesome -- what's going on? |
| 10:49 | Bronsa | ssa: import works at runtime, class literals are resolved at compile time |
| 10:50 | Bronsa | ssa: also in your second import example, you're missing the quote |
| 10:51 | Bronsa | ssa: remember require/import/use & co are functions so when you're using them outside the ns macro, you need to quote the args |
| 10:51 | ssa | Bronsa: ah yes, got it |
| 10:52 | ssa | to describe what I'm trying to do: I want to make a retry policy configurable, and don't want to import unnecessary classes |
| 10:52 | ssa | ie, didn't want to import all retry policies |
| 10:59 | mavbozo | ssa: if you know which classes that you will eventually use, why not import them all? |
| 10:59 | mavbozo | ssa: any particular restriction from environment? |
| 11:00 | ssa | mavbozo: maybe I am wrong here; I am running that snippet of code in a prismatic graph node, which I am using as a config |
| 11:01 | ssa | mavbozo: ie, I know a retry policy will be specified by the user, but I don't know which one |
| 11:01 | ssa | mavbozo: is there no cost to importing everything? |
| 11:03 | mavbozo | ssa: jvm will use more Permanent Generation memory |
| 11:04 | mavbozo | ssa: but you can see the usage from, for example, jconsole |
| 11:10 | puredanger | in <= Clojure 1.6, importing a class will also cause it to be loaded, which is in some cases problematic |
| 11:11 | puredanger | that behavior is actually changing in 1.7 |
| 11:11 | puredanger | http://dev.clojure.org/jira/browse/CLJ-1315 |
| 11:11 | ApeShot | So the issue I mentioned above is quite mysterious |
| 11:11 | ApeShot | I commented out everything except for a naked skeleton in my entry point |
| 11:11 | ApeShot | And then it compiled |
| 11:12 | ApeShot | I gradually added everything back until it was at the original state and all compiled |
| 11:12 | ApeShot | I then did lein clean && lein build and I get the null pointer problem |
| 11:12 | ApeShot | excuse me, lein run |
| 11:12 | ApeShot | To make it go away, I have to comment everything out again, lein run, then uncomment out and lein run |
| 11:12 | ApeShot | It runs fine when it builds |
| 11:12 | ApeShot | no errors |
| 11:13 | ApeShot | But it seems that after a lein clean I must go through this ritual of commenting down to a trivial version |
| 11:13 | ApeShot | And then building, and then uncommenting out my code |
| 11:13 | ApeShot | Does this ring any bells with anyone? |
| 11:13 | sdegutis | Hi. What's a good local file backup setup for local files, including closed source Clojure repos? |
| 11:13 | ApeShot | Sounds like some stile class files are hanging around or something |
| 11:13 | sdegutis | I know redundancy is important, and I've heard the word RAID tossed around... |
| 11:14 | mavbozo | ApeShot: i remember a discussion a few months ago here. someone solve that kind of problems just by creating a new directory and copy every file to the new directory |
| 11:16 | ApeShot | mavbozo: I sort of did that. I might create a clean structure from the same template and copy the files in |
| 11:16 | ApeShot | See if that helps |
| 11:16 | clgv | ApeShot: sounds more like your project is somehow relying on stub class files that are not around after "lein clean" |
| 11:16 | clgv | ApeShot: thats theological computer science then ;) |
| 11:16 | ApeShot | clgv: how might I figure out where those classes are, then? |
| 11:16 | ApeShot | clgv: or what sort of code might generate them? |
| 11:17 | clgv | ApeShot: does the documentation of the libraries/frameworks you use state that some namespaces need to be AOT compiled? |
| 11:17 | ApeShot | clgv: this is for a game jam ending on the 31st, so I am not above computer science theology |
| 11:17 | ApeShot | I'm just using play-clj |
| 11:18 | ApeShot | And my own library cljan, which doesn't do anything fancy |
| 11:18 | ApeShot | Well, it does fancy things, but not so far as the administration of the project is concerned |
| 11:18 | ApeShot | Nothing in the play-clj docs indicates any such thing |
| 11:19 | clgv | can you post the complete stack trace? |
| 11:19 | clgv | you can do (compile 'my.evil.namespace) on the repl and then use clojure.stacktrace/print-cause-trace |
| 11:20 | ApeShot | when the problem happens, I can't even do `lein repl` |
| 11:20 | ApeShot | I get the same error |
| 11:20 | ApeShot | Can I ask lein to start a repl without trying to load the main ns? |
| 11:21 | clgv | yeah you can just comment out the :main line |
| 11:21 | ApeShot | In my project.clj |
| 11:21 | ApeShot | ? |
| 11:21 | clgv | yes |
| 11:21 | ApeShot | Cool |
| 11:21 | ApeShot | Thanks. |
| 11:22 | clgv | remove the namespace from :aot vector as well, if it is listed there |
| 11:22 | technomancy | lein update-in : assoc :main clojure.core -- repl |
| 11:22 | ApeShot | Incidentally, I have had some success building play-clj projects for android |
| 11:22 | clgv | technomancy: awesome. "update-in" is new to me |
| 11:22 | technomancy | clgv: it's a fun one |
| 11:22 | ApeShot | But I keep reading that the dalvik GC isn't really up to game-like functionality for clojure's memory profile |
| 11:23 | technomancy | err... dissoc :main, of course |
| 11:23 | clgv | technomancy: what was the procedure to get full stacktraces from leiningen when for example "lein repl" fails? some environment variable? |
| 11:23 | ApeShot | What is the newest intuition about this? |
| 11:23 | technomancy | clgv: proably something in :repl-options |
| 11:25 | clgv | technomancy: humm there is only :caught in the sample - that sounds as if it is operating in a running repl. I meant when the repl startup fails with an exception |
| 11:29 | clgv | ApeShot: can you report what "DEBUG=true lein repl" or same with "lein run" outputs? |
| 11:37 | SagiCZ1 | i get this when running lein test: Could not locate project_name/core_test__init.class or project_name/core_test.clj |
| 11:39 | clgv | SagiCZ1: so you have a require/use somewhere that wants to load project-name/core.test |
| 11:39 | clgv | err: project-name/core-test |
| 11:39 | andyf_ | SagiCZ1: Not sure, but perhaps that is a sign of a mismatch between file names and namespaces defined in them? If you are willing to try out Eastwood, it checks for that quite quickly. https://github.com/jonase/eastwood#installation--quick-usage |
| 11:40 | conner | What would be the most idiomatic way to turn ["x: FOO" 1 2 3 "x: BAR" 4 5 6] into { "FOO" [1 2 3] "BAR" [4 5 6] }? |
| 11:41 | bbloom | lein removed support for jars in lib/ really? |
| 11:41 | bbloom | that's annoying as hell. |
| 11:43 | cbryan | now i remember why i don't use xchat |
| 11:43 | cbryan | sorry for the leavejoin spam |
| 11:43 | ipostelnik | conner (->> (partition-by #(.startsWith % "x: ")) (map (juxt first rest)) (into {})) |
| 11:44 | SagiCZ1 | andyf_: You got it right, i was renaming my project and forgot to renaim dependencies in the test ns |
| 11:44 | SagiCZ1 | (inc andyf_) |
| 11:44 | lazybot | ⇒ 4 |
| 11:46 | cbryan | thanks ipostelnik! im reading the docs on ->>, it seems like it 'just' prevents a sort of nested-hell? |
| 11:46 | nextstep | hello, what's the clojure way for expressing the following pattern. I have some function for mapping stuff in a collection. Some operation inside that function (calling an external program or a service) is very inefficient if i call it just item by item. How can i cleanly group these while still preserving the 1-by-1 mapping??? |
| 11:46 | lazybot | nextstep: Yes, 100% for sure. |
| 11:48 | CookedGryphon | you could do partition on the output and doseq over the resulting batches |
| 11:49 | dbasch | either pmap or futures |
| 11:49 | andyf_ | nextstep: If the collection you are mapping over can be treated as a generic sequence, you could use partition, and then concat afterwards if you want to put the groups back together. |
| 11:49 | cbryan | i just started clojure 3 days ago, and every time i find out about something like `partition-by` I get goosebumps. joy of clojure, indeed |
| 11:49 | SagiCZ1 | ~pmap |
| 11:49 | clojurebot | pmap is not what you want |
| 11:49 | clgv | true |
| 11:53 | nextstep | yeah i think pmap is not a good solution, and i cannot see how partition would not entangle things either. i want to preserve my simple mapping function |
| 11:53 | nextstep | perhaps futures? |
| 11:54 | nextstep | as dbasch mentioned? |
| 11:54 | arohner | nextstep: I'd use partition & concat |
| 11:55 | arohner | also, core.async much better for parallel processing rather than futures |
| 11:55 | andyf_ | futures by themselves won?t group multiple items together. |
| 11:55 | clgv | nextstep: can you b more specific. do you just want to group according to a criterion or do you want to parallelize expensive computation? |
| 11:57 | nextstep | clgv: i have a very big stream, and i apply a simple map to each element |
| 11:57 | nextstep | inside the mapping function |
| 11:57 | nextstep | i call an external program |
| 11:57 | nextstep | but i want to call this program with batches of items, not just an item at a time |
| 11:57 | clgv | well then you have to explicitely partition the items and map over those partitions |
| 11:58 | clgv | provided the external program supports batches |
| 11:59 | clgv | e.g. (defn map-batched [size f coll] (apply concat (map f (partition-all size coll)))) |
| 11:59 | puredanger | you map find the core.async pipeline function to be useful |
| 12:00 | nextstep | clgv: yes, the external program supports batches |
| 12:00 | clgv | nextstep: you can do something as shown above where `f` gets a list of elements, calls your program and returns a list of results |
| 12:01 | nextstep | but i want to avoid that my f function deals with multiple elements |
| 12:01 | nextstep | so i was thinking of using async |
| 12:01 | nextstep | and inside the f function sending items that get grouped |
| 12:01 | nextstep | and then forwarded to the external program |
| 12:01 | nextstep | i have many f functions, some have to deal with batches, some dont |
| 12:02 | nextstep | so it gets very messy |
| 12:02 | clgv | I am not sure about the side constraints of your scenario |
| 12:04 | clgv | you should make explicit descriptions what the interface to that program is conceptually and what exactly your "different functions" are (clojure functions? calls to the program with different parameters? ...) |
| 12:06 | nextstep | clgv: the functions just take one parameter, the element of the collection to map |
| 12:06 | nextstep | the external functions take many of these |
| 12:07 | clgv | what are "external functions"? |
| 12:07 | nextstep | unix programs that take thousands of items in one go |
| 12:07 | nextstep | or REST services |
| 12:08 | clgv | ok. |
| 12:08 | andyf_ | I?m pretty sure I?ve heard comments about core.async such as ?and it didn?t require changes to Clojure at all. Clojure is such that it could be implemented just as a library.? That is certainly true, but does it seem slightly disingenuous, in that part of that library is a reimplementation of most of the Clojure compiler (i.e. tools.analyzer{,.jvm,.js}) ? |
| 12:08 | andyf_ | ugh. stupid smart quotes |
| 12:08 | nextstep | clgv: therefore grouping items makes it much faster |
| 12:08 | danners | so i am reading through http://www.braveclojure.com/ and now i am on the vampire example. i get following error in the replArityException Wrong number of args (1) passed to: core/map clojure.lang.AFn.throwArity (AFn.java:429) . how do i know where my mistake in my clojure program is from this? |
| 12:08 | nextstep | but i want to hide that from the main program |
| 12:09 | nextstep | this is probably some kind of Go pattern, forward stuff to a proxy that groups calls and gets back with results |
| 12:09 | clgv | nextstep: ok. so where is the problem to just write one function that deals with batching, sending to external program and concatenating the results again. this function would completely hide the abtching except for a batch size parameter |
| 12:09 | nextstep | but havent figured out |
| 12:09 | nextstep | yes |
| 12:10 | nextstep | but i havent been able to figure out a clean solution |
| 12:10 | cbryan | danners: check the stack trace |
| 12:10 | SagiCZ1 | danners: hi, this means that the map didnt get the correct number of args |
| 12:10 | clgv | well I gave you a sketch of it above. you just have to specify what the variable part is that changes |
| 12:11 | SagiCZ1 | cbryan: i have never found my mistake using stacktrace in clojure |
| 12:11 | cbryan | should be like "AFN.throw...AFN.invoke...yournamespace.yourtcode (blah.clj:2025)" |
| 12:11 | danners | cbryan: ah thanks |
| 12:11 | clgv | nextstep: can't you come up with examples how the map+batch should be invoked? |
| 12:11 | danners | thats why it also shows the stacktrace... |
| 12:11 | cbryan | SagiCZ1: yeah, but he asked how to know where the error was :) |
| 12:12 | nextstep | clgv: (defn map-batched [size f coll] (apply concat (map f |
| 12:12 | nextstep | (partition-all size coll)))) |
| 12:12 | nextstep | you mean this sketch? |
| 12:12 | justin_smith | ApeShot: just reading some scrollback, FYI it's normal to include a larger variety of things in one clj namespace than in eg. a java class file. And a project need not have any core.clj file, not to mention having more than one. Lein templates use that name because they need something generic, but a more descriptive name for a namespace is always better. |
| 12:13 | clgv | yeah. it shows a basic principle - I couldnt be more specific since I have no idea what a variable `f` would look like in your case. |
| 12:13 | noncom | i need to support clojure syntax and formatting in emacs, but without support for anything else clojure - what is my best option ? |
| 12:14 | clgv | so in that example it is a function that executes on batches, could also be change to (defn map-batched [size call-external coll] (apply concat (map (fn [coll] (call-external (prepare-params coll))) (partition-all size coll)))) |
| 12:15 | nextstep | clgv: ok let me figure this out, only started using clojure a few days ago, so im a bit slow :) |
| 12:17 | clgv | nextstep: ok, just identify the changing params to such a function as sketched above |
| 12:19 | nextstep | clgv: i dont think i get your proposed solution. I want to call the external program from inside the mapping function like (map (fn [i] ... (call-external j)) coll) |
| 12:20 | nextstep | my mapping function makes some changes to the item i of the collection coll |
| 12:20 | nextstep | on a case per case basis |
| 12:21 | nextstep | so i think its the only way to go, and hide from the function the fact that calling this program on a case per case basis is expensive |
| 12:21 | clgv | nextstep: well, separate the manipulation of the elements from the sending to the program |
| 12:22 | clgv | nextstep: you can easily do (map call-external (map preprocess-element coll)) |
| 12:22 | clgv | nextstep: then it is easy to sneak in the batching |
| 12:23 | clgv | e.g. (map-batched 100 call-external (map preprocess-element coll)) |
| 12:24 | CookedGryphon | Is there a way to get a channel which closes at the same time as a mult, but doesn't get any of the values out of it |
| 12:24 | CookedGryphon | without tapping and just filtering everything |
| 12:26 | clgv | nextstep: the same applies to postprocessing btw |
| 12:27 | nextstep | clgv: aha, ok |
| 12:28 | nextstep | clgv: thanks for your patient explanations :) |
| 12:28 | clgv | you are welcome |
| 12:30 | EvanR | can i get a map pretty print that is actually readable? |
| 12:31 | EvanR | alternating lines of keyname value on the same column is not |
| 12:32 | justin_smith | EvanR: beyond a certain size clojure.pprint does the right thing |
| 12:32 | EvanR | i disagree |
| 12:33 | justin_smith | oh, I misread what you were saying |
| 12:33 | llasram | EvanR: you can try https://github.com/brandonbloom/fipp |
| 12:33 | SagiCZ1 | ,(clojure.pprint/pprint {:a 0 :b 2}) |
| 12:33 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint> |
| 12:33 | justin_smith | so what behavior do you actually want? |
| 12:33 | EvanR | i cant see where entries begin or end |
| 12:33 | borkdude | I miss a decent pretty printer that is usable from clojure and clojurescript |
| 12:34 | EvanR | ive take this for granted so much i can only think of php's print_r as an example of showing a map |
| 12:34 | clgv | llasram: fipp is not much better than pprint |
| 12:34 | EvanR | which i know sounds ridiculous |
| 12:35 | justin_smith | EvanR: is that so much different? you get keys in one column, vals in another |
| 12:35 | llasram | clgv: Except that it's much easier to modify how it prints |
| 12:35 | bbloom | clgv: what's the problem? |
| 12:35 | EvanR | pprint is optimizing for having very little screen width, which makes sense in intellij |
| 12:35 | EvanR | justin_smith: i dont get keys in one column values in another |
| 12:35 | justin_smith | EvanR: the width is configurable |
| 12:35 | bbloom | both clojure.pprint and fipp offer configurable widths |
| 12:35 | EvanR | oh really |
| 12:36 | bbloom | do you want pretty printing for debugging? |
| 12:36 | bbloom | tree whidbey |
| 12:36 | bbloom | try* whidbey rather |
| 12:36 | EvanR | yes, and ok. checking on this width thing |
| 12:36 | bbloom | https://github.com/greglook/whidbey |
| 12:36 | EvanR | "miser-width" |
| 12:37 | borkdude | bbloom does that also work with a browser repl? |
| 12:37 | bbloom | borkdude: no |
| 12:37 | clgv | llasram: yeah some options are better to use |
| 12:37 | SagiCZ1 | once i change ns from 'user' i cant access pprint anymore via 'pprint' .. someone suggested 'injections' in leiningen but it doesnt work for me.. what can i do to be able to always use pprint whenever i want? |
| 12:37 | bbloom | EvanR: i'm bias, as i wrote fipp and whidbey is built on fipp, but if you're looking for a good pretty printer for interactive debugging, whidbey is the way to go |
| 12:38 | bbloom | EvanR: it's faster and the output is less ambiguous (ie supports records and things) compared to pprint |
| 12:38 | clgv | llasram: bbloom: but I didnt gain much with fipp in comparison to pprint for nested data structure |
| 12:38 | EvanR | how do i configure this global variable, *print-miser-width* |
| 12:38 | bbloom | clgv: but you lose the multi-second delay that sometimes happens when printing large structures with clojure.pprint |
| 12:40 | clgv | bbloom: I didn't want to criticize your lib in general. I just wanted to provide the information that I experienced the same with respect to how hash-maps are printed |
| 12:40 | bbloom | clgv: i'm not insulted, don't worry :-P i'd like to improve it, if you can explain what's wrong |
| 12:41 | EvanR | set! set def |
| 12:41 | clgv | bbloom: well that would probably lead to a general lib to format clojure code ;) |
| 12:41 | SagiCZ1 | so how can i keep pprint loaded in repl no matter in what ns i am? |
| 12:41 | bbloom | clgv: fipp has recently added a code pretty printer |
| 12:41 | Shayanjm | are there any well-supported distributed programming packages for clojure? |
| 12:41 | justin_smith | ,(require 'clojure.pprint) |
| 12:41 | clojurebot | nil |
| 12:41 | bbloom | clgv: but it makes no effort to beautify code. that's a non-goal |
| 12:41 | Shayanjm | or is it mostly "just use hadoop"? |
| 12:42 | clgv | bbloom: ah nice. |
| 12:42 | justin_smith | ,(binding [clojure.pprint/*print-miser-width* 200 clojure.pprint/*print-right-margin* 500](clojure.pprint/pprint {:a 0 :b 1 :c 2 :d 3 :e 4 :f 5 :g 6 :h 7 :i 8 :j 9 :k 10 :l 11})) |
| 12:42 | clojurebot | {:e 4, :l 11, :k 10, :g 6, :c 2, ...}\n |
| 12:42 | noonian | SagiCZ1: you can also construct your own user namespace and require what you like there |
| 12:42 | cbryan | Shayanjm: Storm |
| 12:42 | justin_smith | ,(clojure.pprint/pprint {:a 0 :b 1 :c 2 :d 3 :e 4 :f 5 :g 6 :h 7 :i 8 :j 9 :k 10 :l 11}) |
| 12:42 | clojurebot | {:e 4, :l 11, :k 10, :g 6, :c 2, ...}\n |
| 12:42 | Shayanjm | cbryan: much appreciated, will look into it |
| 12:42 | Shayanjm | will be building a big crawler/scraper project |
| 12:42 | bbloom | clgv: fipp provides generic pretty printing infrastructure for *fast* pretty printers. where pretty printing is defined as an indenter that respects the right margin |
| 12:42 | Shayanjm | will likely need a LOT of parallelization |
| 12:42 | SagiCZ1 | justin_smith: so whenever i change ns i have to call the require function? sure there must be a better way.. |
| 12:42 | bbloom | full on code beautification is a much harder problem and one for which a generic infrastructure can't make good performance promises |
| 12:42 | mdrogalis | Shayanjm: If you can afford a little more risk with a newer project, I released Onyx about a month ago. |
| 12:43 | justin_smith | EvanR: without the truncation clojurebot does, one of those would have had newlines, the other not |
| 12:43 | cbryan | Shayanjm: https://storm.apache.org/ |
| 12:43 | Shayanjm | mdrogalis: could probably afford risk. I'll look into both. What does onyx provide over storm? |
| 12:43 | SagiCZ1 | bbloom: yeah, you need fuzzy logic and genetic algorithms! |
| 12:43 | bbloom | SagiCZ1: not really, but you do need context sensitivity |
| 12:43 | justin_smith | SagiCZ1: not change ns? I wasn't showing that to demonstrate how you should handle things though, I was trying to demonstrate the pprint control parameters |
| 12:43 | technomancy | SagiCZ1: there is no good in-clojure solution for keeping stuff like pprint available everywhere. IMO that needs to be handled by your repl tools. |
| 12:43 | mdrogalis | Shayanjm: https://github.com/MichaelDrogalis/onyx/blob/0.3.x/doc/user-guide/what-does-it-offer.md |
| 12:43 | bbloom | which you can encode in to your transformation from your source data in to the "pretty document" format of fipp |
| 12:44 | EvanR | justin_smith: i have to wrap every pprint in this binding? |
| 12:44 | SagiCZ1 | justin_smith: oh sorry |
| 12:44 | Shayanjm | interesting mdrogalis |
| 12:44 | justin_smith | EvanR: or you could set those bindings at the top level with the help of lein |
| 12:44 | Shayanjm | are you actively maintaining the project? |
| 12:44 | cbryan | mdrogalis: very cool |
| 12:44 | bbloom | but choosing an optimal layout may involve speculatively trying various layouts, which fipp explicitly disallows b/c it can be slow |
| 12:44 | SagiCZ1 | so when developing do you usually stay in user ns and load everything in there? |
| 12:45 | mdrogalis | Thanks. Next release might be out tomorrow morning. One more bug I want to fix before I unleash a bunch more features. |
| 12:45 | justin_smith | SagiCZ1: I make experiments in the user ns, define the final version of my code in a file, then require that file |
| 12:45 | justin_smith | SagiCZ1: that's not the only way to do it of course |
| 12:47 | EvanR | justin_smith: well, now its all on one line |
| 12:48 | clgv | SagiCZ1: I am a namespace nomad. always switching to the namespaces where I need to dev something - or in a namespace that is using the ns to change |
| 12:49 | justin_smith | EvanR: I still have no idea what behavior you are actually looking for, you named a php function I googled it, and it had things in two columns in the example I saw |
| 12:49 | EvanR | i have yet to get pprint to do that |
| 12:49 | EvanR | even that |
| 12:50 | technomancy | SagiCZ1: I typically use cider commands instead of calling tooling like that in the repl |
| 12:50 | technomancy | SagiCZ1: nrepl-discover makes it super easy to expose arbitrary functions like pprint or trace from cider |
| 12:50 | EvanR | i can coerce it to do one of two things. one is {k v k v k v k v} the other is |
| 12:50 | EvanR | k |
| 12:50 | technomancy | should be easy to do from vim or ccw or whatever too |
| 12:50 | EvanR | v |
| 12:50 | EvanR | k |
| 12:50 | EvanR | v |
| 12:50 | justin_smith | EvanR: do you have long v values? |
| 12:51 | EvanR | no they are all nested other things |
| 12:51 | EvanR | i have a string at the bottom somewhere which is "SecondAndFurtherGivenNamesOrInitialsThereof" |
| 12:52 | EvanR | if it just always did |
| 12:52 | EvanR | k v |
| 12:52 | EvanR | k v |
| 12:52 | EvanR | regardless of content then i would be ok |
| 12:54 | EvanR | heres an example http://codepad.org/1zndckFV |
| 12:54 | EvanR | of what pprint never does |
| 12:54 | EvanR | for me |
| 12:57 | bbloom | EvanR: that code is not pretty printed with respect to a right column, it's simply indented |
| 12:58 | SagiCZ1 | justin_smith, clgv, technomancy thanks for opinions, interesting to see that there is not just one "correct" way |
| 12:58 | bbloom | EvanR: if you set the width to 0 (or 1?), you can force maximum indenting |
| 12:58 | EvanR | ill try that |
| 12:59 | bbloom | the reason you don't typically see json style indenters for lisps is b/c they are practically useless |
| 12:59 | bbloom | most sequences are short enough that it doesn't make sense to spread them over multiple lines |
| 13:00 | bbloom | and since lists are so common, it would be hideous to see "(\t\nfoo\t\nbar\n)" |
| 13:00 | EvanR | i dont have a single list |
| 13:00 | EvanR | this is a map |
| 13:00 | bbloom | sure, so if yuo really just want indenting for it, then set the width to 1 |
| 13:00 | EvanR | i set the width to zero, and it did some stuff, seems like everything except put the k and value not on alternating lines with the same colum |
| 13:01 | bbloom | i can't speak for pprint with width = 1, but my library fipp will do what you expect |
| 13:02 | bbloom | whidbey probably will do the right thing too, but I can't say for sure as it's only using my printing engine, not my specific printer |
| 13:02 | EvanR | that is to say, width zero causes k and v to be on alternating lines |
| 13:02 | bbloom | EvanR: may i ask why you want this anyway? |
| 13:02 | bbloom | ie why is the default behavior not good enough? |
| 13:02 | EvanR | i cant read my json-like data? |
| 13:03 | EvanR | k |
| 13:03 | EvanR | v |
| 13:03 | EvanR | k |
| 13:03 | EvanR | v |
| 13:03 | EvanR | i cannot read it |
| 13:03 | EvanR | anymore than if it was k v k v k v on one line |
| 13:03 | EvanR | in this case, it is the transpose, all on one column |
| 13:03 | EvanR | with no separation |
| 13:04 | bbloom | *shrug* ok well, most people find it more readable for small collections to be horizontally laid out, so i don't really know if i can help you |
| 13:04 | bbloom | try fipp with width set to 1 |
| 13:04 | bbloom | it always keeps key/value pairs together on a single line no matter what |
| 13:04 | tolstoy | ll |
| 13:04 | tolstoy | Oops. ;) |
| 13:04 | EvanR | also, the default behavior does indent, by one space. which is fine, but its just incomprehensible with the k v on alternating lines, which i guess its calling "miser style" |
| 13:04 | EvanR | bbloom: small collections? |
| 13:05 | EvanR | just to be clear, its not horizontally laid out, its very vertical |
| 13:06 | bbloom | EvanR: i understand, but you don't: pprint (and fipp) attempt to make a non-stupid layout. they do not blindly indent everything |
| 13:07 | bbloom | things will be laid out horizontally if they fit, or vertically if they don't |
| 13:07 | bbloom | hence width = 1 means nothing fits |
| 13:07 | bbloom | however, clojure.pprint will let keys and values be separate, fipp will not |
| 13:07 | bbloom | so try fipp with width = 1 |
| 13:07 | EvanR | i can see where the reasoning came from for this |
| 13:08 | katratxo | hi all, any hints on changing the logging level of a namespace at runtime? i'm using tools.logging |
| 13:08 | bbloom | try (clojure.pprint/pprint [(repeat 3 :short) (repeat 10 :some-longer-keyword)]) and you'll understand |
| 13:09 | EvanR | i have a lot of horizontal space, but if i set the width to very wide, it will do k vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv k vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv which im trying to say is very in convenient |
| 13:09 | justin_smith | katratxo: there is such thing as per namespace variable logging levels in tools.logging? |
| 13:09 | bbloom | EvanR: i'm done with this conversation until you tell me you've tried fipp with width = 1 |
| 13:09 | EvanR | ill say again, im talking about record-like maps, with field names and keys, its not some generic collection concept |
| 13:09 | clgv | justin_smith: there is per java class |
| 13:10 | EvanR | fipp is installed, trying |
| 13:10 | bbloom | (fipp.edn/pprint {:foobar 123 :baz "asdfasdf"} {:width 1}) does exactly the thing you want |
| 13:11 | katratxo | justin_smith: not sure about that ... the documentation suggests that you can define the logging level of a namespace (at least with log4j) |
| 13:12 | clgv | katratxo: yeah I have seen it per java class |
| 13:13 | justin_smith | katratxo: oh, I did not see anything like that in the api overview doc page. But timbre explicitly supports per-namespace control |
| 13:13 | clgv | katratxo: you can modify system properties for logging |
| 13:14 | samflores | is there some roadmap for core.async leaving alpha? |
| 13:15 | clgv | samflores: sssshhh! you are openening pandora's box :P |
| 13:15 | samflores | 👀 |
| 13:15 | EvanR | im getting no namespace fipp.edn |
| 13:16 | EvanR | and no namespace fipp.clojure |
| 13:16 | katratxo | justin_smith: do you know if timbre can capture the System.out and redirect it to a log? similar to log/with-logs ? |
| 13:16 | bbloom | EvanR: i'm happy to offer you support for fipp, but i'll leave general "how do i use clojure" support to the rest of the channel |
| 13:16 | EvanR | yeah |
| 13:16 | justin_smith | katratxo: not sure, doesn't it use tools.logging? |
| 13:16 | clgv | samflores: last time this discussion happened, I had the impression that the maintainers think that human rememberable versions have no use |
| 13:17 | katratxo | justin_smith: will check it out ... thanks |
| 13:22 | EvanR | frustrated now |
| 13:23 | EvanR | i have [fipp "0.5.1"] in my project.clj, lein deps does nothing |
| 13:23 | EvanR | (require '[fipp.edn]) in lein repl gives CompilerException java.lang.RuntimeException: Unable to resolve symbol: record? in this context, compiling:(fipp/edn.clj:42:11) |
| 13:23 | samflores | clgv, I guess I'll wait quietly then |
| 13:24 | llasram | EvanR: That function was added in Clojure 1.6 |
| 13:25 | llasram | EvanR: Using an older version? |
| 13:25 | EvanR | Clojure 1.5.1 |
| 13:25 | llasram | Well there you go |
| 13:26 | EvanR | what am i doing with an old version |
| 13:26 | llasram | A question humans throughout history have asked themselves |
| 13:27 | EvanR | this is ubuntu 14.04 |
| 13:27 | llasram | eh? |
| 13:27 | llasram | EvanR: Clojure version is per-project, a feature of what you have in your Leiningen project.clj |
| 13:27 | EvanR | oh k |
| 13:28 | bbloom | if you installed leinigen with apt, you should uninstall it and use the preferred install method |
| 13:28 | bbloom | http://leiningen.org/ |
| 13:28 | EvanR | [org.clojure/clojure "1.5.1"] is in my project file so that explains that, also i installed leiningen the way the site told me to |
| 13:29 | llasram | Awesome |
| 13:29 | EvanR | so ubuntu fortunately has nothing to do with it |
| 13:29 | technomancy | babilen: hate to be a broken record, but what's the odds of lein2 getting into debian jessie? |
| 13:29 | EvanR | so fipp depends on a particular version of clojure |
| 13:30 | bbloom | EvanR: a minimum version of clojure, yes |
| 13:30 | EvanR | shouldnt lein deps tell me? |
| 13:30 | EvanR | good time to go to lunch |
| 13:31 | technomancy | EvanR: there's no way to distinguish between "minimum version" and "recommended version" in pom-speak |
| 13:31 | EvanR | pom pom ... |
| 13:31 | EvanR | Project Object Model |
| 13:33 | technomancy | EvanR: however, lein deps :tree will warn you about this |
| 13:33 | technomancy | [org.clojure/clojure "1.5.1"] overrides [fipp "0.5.1"] -> [org.clojure/clojure "1.6.0"] |
| 13:44 | csd_ | where's the best place to host a small clojure web app for free? |
| 13:44 | r4vi | heroku |
| 13:45 | csd_ | r4vi: only downside there is they use postgres and i made this with mysql :-/ |
| 13:45 | technomancy | there are mysql addons too; we just don't run them ourselves |
| 13:45 | technomancy | but, maybe that's a good excuse to stop using mysql =) |
| 13:46 | csd_ | technomancy: you work for heroku? |
| 13:46 | technomancy | yeah |
| 13:46 | csd_ | cool |
| 13:47 | technomancy | lemme know if you have any questions |
| 13:47 | csd_ | technomancy: do you think the server will complain if my app does some minor web scraping? |
| 13:47 | technomancy | csd_: shouldn't be a problem |
| 13:47 | technomancy | I mean, please respect the terms of service of the site being scraped, but that has nothing to do with us =) |
| 13:52 | xeqi | EvanR: `lein deps :tree` should produce some warnings about version mismatches, though that was broken for a couple of point releases in 2.4.* |
| 14:32 | justin_smith | ,(deref (doto (promise) (deliver :ping))) |
| 14:32 | clojurebot | :ping |
| 14:49 | borkdude | ,(chan) |
| 14:49 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: chan in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:50 | justin_smith | borkdude: I don't think clojurebot will do anything with threads |
| 14:51 | justin_smith | borkdude: blame the bot quine |
| 14:51 | borkdude | justin_smith you don't need threads per se for core.async right |
| 14:51 | justin_smith | borkdude: I guess we could port clj core.async to clojurebot? |
| 14:51 | borkdude | justin_smith clojurescript |
| 14:52 | justin_smith | borkdude: sure, but clojurebot is not clojurescript |
| 14:52 | justin_smith | point being we would need a clj version of core.async that did not use threads |
| 14:52 | borkdude | justin_smith k, well, one liners don't work well with core.async anyway probably |
| 14:53 | justin_smith | borkdude: yeah. I would make it easier to show people with questions how core.async stuff works though |
| 14:53 | justin_smith | s/I/It |
| 14:56 | justin_smith | borkdude: actually, a cljsbot would be good too |
| 14:56 | borkdude | justin_smith yeah |
| 14:57 | justin_smith | I wonder if there is a way to do that that isn't totally insane |
| 14:57 | borkdude | { (js/alert "haha"} } |
| 14:57 | borkdude | justin_smith could look at clojurescript.net? |
| 15:01 | justin_smith | yeah, that would likely be a good start |
| 15:02 | justin_smith | borkdude: they link to this as their source https://github.com/kanaka/clojurescript |
| 15:03 | justin_smith | mix that with Raynes irc lib, and bob's your uncle |
| 15:04 | perplexa | is there a better way to do (fn [a & option] (or option "default"))? |
| 15:05 | justin_smith | ,((fn [a & option] (or option "default")) nil nil) |
| 15:05 | clojurebot | (nil) |
| 15:06 | justin_smith | ,((fn [a & [option]] (or option "default")) nil nil) |
| 15:06 | clojurebot | "default" |
| 15:06 | danielszmulewicz | I would like to emit javascript to a string. Not via the cljs build process, but by using the compiler directly from source. Input is some clojure form (defn three+three [] (+ 3 3)), output should be: "node_test.core.three_PLUS_three = (function three_PLUS_three(){return ((3) + (3));" How do I achieve that? |
| 15:07 | perplexa | ah, so & pushes the following params into a seq |
| 15:07 | justin_smith | perplexa: yeah, because it takes any number of params |
| 15:08 | perplexa | yeah makes sense :) |
| 15:23 | SagiCZ1 | would it benefit me to create a memoized version of count? i use count often and the linear time is really slow for me |
| 15:24 | mgaare | SagiCZ1: do you often find yourself counting the same thing multiple times? |
| 15:25 | SagiCZ1 | mgaare: yeah |
| 15:26 | SagiCZ1 | i guess thats a bad design though |
| 15:26 | justin_smith | SagiCZ1: you could use vectors or sets instead of lazy-seqs where applicable, they implement count in constant time |
| 15:26 | SagiCZ1 | vectors count is constant? |
| 15:26 | justin_smith | yup |
| 15:26 | SagiCZ1 | thats cool then, i use vectors mostly |
| 15:26 | bbloom | SagiCZ1: putting a memo table at the call site is likely to be a memory management nightmare -- justin_smith is right, prefer better data structures |
| 15:26 | SagiCZ1 | thanks |
| 15:27 | mmeix | If I want to partition a sequence of numbers, so that consecutive numbers are packed into separate vectors like so: |
| 15:27 | mmeix | [1 2 3 5 6 9 12 13] => '([1 2 3] [5 6] [9] [12 13]) |
| 15:27 | mmeix | partition-by doesn't help me much, because it only looks at one element at a time |
| 15:27 | justin_smith | mmeix: it can be done in a one-liner with reduce |
| 15:29 | mmeix | ok, I guessed this to be a case for reduce |
| 15:29 | mmeix | but didn't get it - will think further |
| 15:29 | hyPiRion | reduce, transduce |
| 15:30 | mmeix | ok |
| 15:30 | mmeix | thanks |
| 15:32 | justin_smith | ,(def input [1 2 3 5 6 9 12 13]) |
| 15:32 | clojurebot | #'sandbox/input |
| 15:32 | justin_smith | ,(reduce (fn [[acc contig] n] (if (= (inc (peek contig)) n) [acc (conj contig n)] [(conj acc contig) [n]])) [[] [(first input)]] (rest input)) |
| 15:32 | clojurebot | [[[1 2 3] [5 6] [9]] [12 13]] |
| 15:32 | justin_smith | wait, that's a bit off isn't it :) |
| 15:33 | justin_smith | ,(apply conj (reduce (fn [[acc contig] n] (if (= (inc (peek contig)) n) [acc (conj contig n)] [(conj acc contig) [n]])) [[] [(first input)]] (rest input))) |
| 15:33 | clojurebot | [[1 2 3] [5 6] [9] [12 13]] |
| 15:33 | SagiCZ1 | beautiful |
| 15:35 | justin_smith | heh, thanks |
| 15:37 | hyPiRion | I feel this problem pops up quite often for some reason. And I always want to use (partition 2 1 ...) on it and it gets all messy |
| 15:37 | hyPiRion | it's for some reason not as straightforward to implement it |
| 15:37 | mmeix | ah, missed that because of laptop sleep (after (def input...) |
| 15:37 | justin_smith | hyPiRion: yeah, my goto for that is multi-accumulator reduce |
| 15:37 | justin_smith | mmeix: should I repaste the code? |
| 15:38 | justin_smith | hyPiRion: I wonder if a multi-accumulator version of reduce without destructuring would be worth it? |
| 15:38 | mmeix | tried partition 2 1, got lots of parens ... |
| 15:39 | hyPiRion | justin_smith: multi-accumulator? |
| 15:39 | mmeix | justin_smith if you would be so kind ... |
| 15:39 | justin_smith | ,(apply conj (reduce (fn [[acc contig] n] (if (= (inc (peek contig)) n) [acc (conj contig n)] [(conj acc contig) [n]])) [[] [(first input)]] (rest input))) |
| 15:39 | clojurebot | [[1 2 3] [5 6] [9] [12 13]] |
| 15:39 | justin_smith | hyPiRion: I have two accumulator values, thanks to destructuring |
| 15:40 | justin_smith | hyPiRion: but I guess that doesn't make sense beause apply would have to be used internally anyway since you would need to return a collection... |
| 15:40 | justin_smith | hyPiRion: or just use recur, of course |
| 15:40 | mmeix | wow, that's a fat oneliner :-) will study it thoroughly |
| 15:40 | justin_smith | mmeix: doesn't qualify as a one-liner, I don't think |
| 15:41 | justin_smith | mmeix: it's not so bad when on a few lines and indented properly |
| 15:41 | mmeix | just doin that |
| 15:42 | justin_smith | mmeix: so as I was saying, the main trick is using destructuring / returning a vector in order to have more than one accumulator |
| 15:42 | mmeix | ah, that's a new technique for a beginner |
| 15:43 | mmeix | ah: that was the point I couldn't get: "multiple accumulators" |
| 15:43 | mmeix | thanks a lot |
| 15:44 | mmeix | (inc justin_smith) |
| 15:44 | lazybot | ⇒ 108 |
| 15:44 | hyPiRion | It's not very common I think |
| 15:45 | justin_smith | hyPiRion: I do it often, maybe it's because I am weird |
| 15:45 | mmeix | this is something I expect to need a lot: segemnting vectors of musical notes by some criterion |
| 15:45 | mmeix | thanks for input! |
| 15:46 | hyPiRion | mmeix: oh, just a warning: That one won't work on infinite lists |
| 15:46 | mmeix | understand ... |
| 15:47 | mmeix | I don't expect my musical phrases to be of infinite length though :-) |
| 15:47 | justin_smith | mmeix: I bet you could do some fun stuff with derive and multimethods to describe musical rules |
| 15:47 | mmeix | derive? (looking up) |
| 15:48 | mmeix | ok, have to leave |
| 15:48 | mmeix | thanks again |
| 15:48 | justin_smith | np |
| 15:50 | justin_smith | hyPiRion: I guess a lazy version could be done with (partition 2 1 ...) and take-while |
| 15:50 | justin_smith | and lazy-seq of course |
| 15:58 | arohner | running new Cider (installed from melpa today), I don't get stacktraces when an error occurs. The error window pops up, but it's empty |
| 15:58 | arohner | any ideas? |
| 15:59 | arohner | FWIW, my previous version didn't have working stacktraces either, which is why I tried to upgrade |
| 15:59 | arohner | I got the error about missing the cider-nrepl .jar, but I fixed that |
| 15:59 | justin_smith | arohner: I assume you can at least use (pst) |
| 15:59 | arohner | yeah |
| 15:59 | technomancy | have you tried the stable version? |
| 16:00 | arohner | technomancy: which one is that? from melpa-stable? |
| 16:00 | justin_smith | arohner: 0.7.0 |
| 16:01 | justin_smith | arohner: also, the clojure-emacs channel has at least one cider dev who doesn't follow this channel on it |
| 16:01 | technomancy | arohner: 0.7.0 and 0.6.0 are both a lot more likely to work than whatever melpa gives you |
| 16:01 | technomancy | melpa-stable will probably give you 0.7.0 claiming to be some nonsense datestamped version |
| 16:02 | arohner | justin_smith: technomancy: thanks |
| 16:02 | arohner | technomancy: how do you recommend I install it? |
| 16:02 | technomancy | arohner: I ... =( |
| 16:02 | technomancy | I don't have a recommendation. |
| 16:02 | arohner | git clone and stick in ~/.emacs.d/? |
| 16:02 | technomancy | if you use emacs 24.3, you can install from marmalade |
| 16:02 | technomancy | but emacs 24.4 has a bug that breaks transitive deps over HTTPS |
| 16:03 | technomancy | obviously don't install over non-TLS (melpa, melpa-stable) |
| 16:03 | technomancy | so yeah, manual clone is nice because you're in control, but the deps are tedious to track down |
| 16:03 | arohner | I think marmalade gave me 0.6.0, which also didn't work |
| 16:03 | arohner | but sounds like that's more likely to get working |
| 16:04 | technomancy | el-get works, but I can't recommend it out of the box, it's only safe to use if you (setq el-get-allow-insecure nil) |
| 16:04 | technomancy | I'm using 0.6.0 |
| 16:04 | dysfun | i think life would be particularly miserable without melpa |
| 16:04 | dbasch | I had problems with 0.7.0, sticking to 0.6.0 because it works fine for me |
| 16:04 | technomancy | all the package.el sources are fatally flawed at the moment |
| 16:05 | technomancy | unless you use marmalade and hold off on the emacs 24.4 upgrade |
| 16:05 | dysfun | yeah, but it's still pretty new tech |
| 16:05 | technomancy | dysfun: that's not a good excuse |
| 16:05 | technomancy | even if it were true, which it's not |
| 16:06 | dysfun | frankly, pre-melpa, i didn't bother at all |
| 16:06 | dysfun | because there just wasn't enough stuff available |
| 16:06 | csd_ | technomancy: question about heroku |
| 16:06 | technomancy | dysfun: now you're installing software in a way that's trivial to MITM. is this an improvement? |
| 16:06 | arohner | ok, so I'm back on cider 0.6.0, and stacktraces don't pop up in a buffer |
| 16:06 | technomancy | csd_: sure, go ahead |
| 16:06 | arohner | I just get the first line of the stacktrace in the repl |
| 16:07 | csd_ | i'm trying to deploy and i'm running into a boot timeout error. my app is getting killed while its compiling basically. would this recompile happen every time the dyno restarts? |
| 16:07 | dysfun | technomancy: i *have* installed software in a way that is trivial to MITM. And probably won't be MITMed. and i try not to live my life in a tinfoil hat manner |
| 16:07 | justin_smith | arohner: I think there is a config variable for that |
| 16:07 | technomancy | dysfun: well, luckily I don't use any software you've released in a production setting where user data is at stake |
| 16:08 | arohner | justin_smith: I have (setq cider-show-error-buffer t) |
| 16:08 | technomancy | csd_: that's common if you're not creating an uberjar at git push time. the uberjar approach is strongly recommended for this reason. |
| 16:08 | dysfun | technomancy: everything you use is already backdoored and you're worried about a highly improbable event instead? |
| 16:09 | technomancy | dysfun: the level of sophistication to pull off an HTTP MITM is laughably low |
| 16:09 | csd_ | do people that take that tack include the .jar in their git repo? |
| 16:09 | dysfun | how many times do you think i'm going to have to install a package from elpa? |
| 16:09 | csd_ | or is there another way to upload it |
| 16:09 | dysfun | melpa* |
| 16:09 | clojurebot | A nod, you know, is as good as a wink to a blind horse. |
| 16:09 | llasram | clojurebot: or? |
| 16:09 | clojurebot | or is there another way to upload it |
| 16:09 | technomancy | csd_: no, you push the git repo to the build servers and the uberjar is created there |
| 16:10 | technomancy | dysfun: this is basic computing hygiene |
| 16:10 | technomancy | "don't put that in your mouth, you don't know where it's been" of ones and zeroes |
| 16:10 | dysfun | i suppose you have a strip of tape over your webcam just in case the NSA is watching too |
| 16:11 | technomancy | it's one thing to guard against a nation state adversary, it's another to guard against attacks that are trivial to preform |
| 16:11 | dysfun | i'm not arguing the services shouldn't be better, but there are much bigger things for me to worry about |
| 16:11 | csd_ | technomancy: guessing i just need to specify :uberjar-name in project.clj and that should take care of things? |
| 16:11 | technomancy | csd_: yeah |
| 16:11 | dysfun | i install elisp from melpa once in a blue moon. i'm not going to get paranoid about that |
| 16:11 | csd_ | cool thanks |
| 16:11 | technomancy | csd_: and change your procfile to use the uberjar instead of lein run or whatever |
| 16:12 | justin_smith | dysfun: he's someone who works on the dependency resolution and deployment stack, I'd say he's doing us a favor by letting us know when something is sketchy, and we can decide how to act on that info |
| 16:12 | csd_ | is there a way to do lein ring server-headless via uberjar |
| 16:13 | technomancy | my laptop has credentials that would allow me to steal data from customers that include bitcoin exchanges. |
| 16:13 | dysfun | you mean you want your main class to start a server? |
| 16:13 | dysfun | ah. well i certainly wouldn't keep credentials like that on here |
| 16:14 | technomancy | if I use a dysfun-produced jar in one of my projects, I've created a large incentive for someone to attack melpa. |
| 16:14 | dysfun | on the other hand, since all of my modules are on github, you can read the source |
| 16:14 | technomancy | there would be very little technically challenging about pulling off this attack |
| 16:15 | technomancy | dysfun: I'm not going to build from source, I'm going to get it from clojars. |
| 16:16 | technomancy | even if I built from github, you probably haven't disable force-push on your repos |
| 16:16 | dysfun | see, that sounds like a terrible idea now, because you never know that all of those people releasing to clojars are quite as careful as you |
| 16:17 | dysfun | but my point about it being on github was merely that if you don't trust the code, you can read it and determine if it's a risk |
| 16:17 | technomancy | it is pretty terrible, but at least clojars can't be trivially MITM'd any more. |
| 16:17 | technomancy | there are really easy things you can do to prevent simple attacks. |
| 16:17 | technomancy | there are really difficult things you can maybe do to hopefully prevent sophisticated attacks. |
| 16:18 | dbasch | dysfun: sneaking malicious obfuscated code in open source is trivial and it’s been done |
| 16:18 | technomancy | just because some of it is hard doesn't mean the easy stuff isn't worth bothering with. |
| 16:18 | TimMc | dysfun: I do in fact keep a sticky note over my webcam. It's easy and makes sense. |
| 16:18 | dysfun | dbasch: thousands of times. thousands of times in linux alone i'd wager |
| 16:19 | TimMc | It's not weird to guard against attacks that have already happened to other people. |
| 16:19 | dbasch | not like anybody ever looks at the source code of even a fraction of what they run blindly |
| 16:19 | technomancy | I don't have a webcam, FWIW. |
| 16:19 | justin_smith | TimMc: dysfun: I leave mine uncovered, the sight any attacker would witness if they turned it on would be its own punishment |
| 16:19 | dysfun | technomancy: no. but on the other hand, the fact that i'm going to install each package precisely once does somewhat limit the vector of attack |
| 16:19 | technomancy | but the fact that they aren't hard-wired into the activity LED pisses me off |
| 16:19 | dysfun | they are on some laptops |
| 16:20 | TimMc | technomancy: Even that doesn't help -- you can turn it on, take a picture, and turn it off again without the user noticing. |
| 16:20 | dbasch | listening in on someone is much more useful than looking at them with a camera anyway |
| 16:20 | dysfun | exactly |
| 16:20 | dbasch | tracking your keystrokes even more so |
| 16:20 | TimMc | Microphones are even worse, of course. No activity light. |
| 16:20 | justin_smith | my favorite recent conspiracy theory: FBI complains loudly about google / apple not giving them back doors into their mobile systems as a cover for the fact that they already have access |
| 16:20 | dysfun | and of course there was that malware that used microphones and speakers as a back channel too |
| 16:21 | TimMc | Anyway, point is, it's silly to not take precautions where there's low cost and high gain. |
| 16:21 | TimMc | And layered security is a thing. |
| 16:21 | dysfun | and it would be lovely if it was there, don't get me wrong |
| 16:22 | dysfun | i would like to see SSL be used everywhere, all the time |
| 16:26 | bodie_ | anyone tried cursive with clojurescript? |
| 16:26 | bodie_ | IDEA fork built around lein I guess? |
| 16:27 | bodie_ | I've been using lighttable but its cljs integration is a little wack |
| 16:27 | justin_smith | bodie_: it's an idea plugin by cfleming that uses lein |
| 16:27 | mdrogalis | GitHub changed Clojure code highlighting. Do not like D: |
| 16:27 | SagiCZ1 | bodie_: i've been using cursive for weeks now |
| 16:27 | SagiCZ1 | bodie_: but only clojure |
| 16:27 | borkdude | bodie_ yes, works with clojurescript |
| 16:27 | bodie_ | hm |
| 16:27 | bodie_ | interesting |
| 16:28 | borkdude | bodie_ in the sense of highlighting etc |
| 16:28 | borkdude | bodie_ I build from lein cljsbuild externally |
| 16:30 | boblarrick | how do I flatten something like [ [1 2 3] :b 'a] into (1 2 3 :b 'a) ? |
| 16:30 | bodie_ | borkdude, do you have a live browser setup you like? i.e. auto refresh, eval from the repl perhaps |
| 16:30 | bodie_ | I've been really digging the decently tight integration lighttable has there |
| 16:30 | borkdude | bodie_ you can have a look at lein new liberagent, that's basically my setup |
| 16:30 | borkdude | bodie_ it's inspired by chestnut |
| 16:31 | borkdude | I want to cover om + reagent in a 40 minute talk... I think I'm already short in time |
| 16:32 | boblarrick | (reduce conj …) i guess |
| 16:32 | justin_smith | boblarrick: apply conj would suffic |
| 16:32 | mdrogalis | reduce/conj is my favorite Clojure idiom, I think. |
| 16:32 | mdrogalis | ,(reduce conj (list) (range 5)) |
| 16:33 | clojurebot | (4 3 2 1 0) |
| 16:33 | justin_smith | ,(apply conj [1 2 3] :b ;a) |
| 16:33 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 16:33 | justin_smith | ,(apply conj [1 2 3] :b 'a) |
| 16:33 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol> |
| 16:33 | justin_smith | err |
| 16:33 | bodie_ | borkdude, so cljsbuild auto + figwheel = live js updating, right? |
| 16:33 | justin_smith | ,(apply conj [[1 2 3] :b 'a]) ; that's what I meant |
| 16:33 | clojurebot | [1 2 3 :b a] |
| 16:34 | borkdude | bodie_ true |
| 16:34 | bodie_ | and then there must be some way to tie in the repl as well |
| 16:34 | borkdude | bodie_ if you read the docs on lein new liberagent it says it all |
| 16:34 | bodie_ | okay, cool |
| 16:34 | bodie_ | was just glancing over the list of deps |
| 16:34 | borkdude | bodie_ fighweel = lein cljsbuild auto + updating |
| 16:34 | justin_smith | mdrogalis: except for conj reduce doesn't do anything apply wouldn't be doing |
| 16:34 | bodie_ | most of it is backend stuff I don't need right now |
| 16:34 | SagiCZ1 | can i map backwards? like this (map #(% coll) [foo1 foo2 foo3 ..]) |
| 16:35 | borkdude | bodie_ just comment them out and remove it |
| 16:35 | justin_smith | SagiCZ1: sure, that works, or you can use juxt |
| 16:35 | bodie_ | yeah, figuring out what I *do* need :) hehe |
| 16:35 | bodie_ | thanks for the pointer! |
| 16:35 | mdrogalis | justin_smith: Eh? Oh, I guess I should've qualified that with "reverse" idiom. Not in general. |
| 16:35 | justin_smith | ,(map #(% [1 2]) [+ * / -]) |
| 16:35 | clojurebot | #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentVector to java.lang.Number> |
| 16:35 | SagiCZ1 | justin_smith: ok |
| 16:35 | justin_smith | ,(map #(apply % [1 2]) [+ * / -]) |
| 16:35 | clojurebot | (3 2 1/2 -1) |
| 16:35 | SagiCZ1 | it says unable to resolve symbol foo1 in this context.. so idk |
| 16:36 | justin_smith | ,(apply (juxt + * / -) [1 2]) |
| 16:36 | clojurebot | [3 2 1/2 -1] |
| 16:36 | justin_smith | SagiCZ1: well you need to define things before you can call them... |
| 16:36 | rubber_duck | can someone point me to a minimal implementation of a transducing process so I can wrap my head arround the spec - it's kind of hard to figure out how to implement one without types :( |
| 16:37 | justin_smith | ,(apply conj () (range 5)) ; mdrogalis |
| 16:37 | clojurebot | (4 3 2 1 0) |
| 16:38 | SagiCZ1 | justin_smith: yeah my mistake.. and can i get name of the function from the IFn object? (name (defn foo [] ..)) |
| 16:38 | justin_smith | SagiCZ1: it sounds like you are trying to do something weird here... |
| 16:39 | SagiCZ1 | justin_smith: yeah.. just want to save some typing |
| 16:39 | SagiCZ1 | let me explain |
| 16:40 | SagiCZ1 | i want to have a map where keywords are made from function names, and values are results of calls to those functions like so {:foo1 (foo1 coll) :foo2 (foo2 coll) ..} |
| 16:41 | rubber_duck | SagiCZ1, IIRC fns don't have names vars do |
| 16:42 | SagiCZ1 | rubber_duck: how would i turn the var name into keyword? |
| 16:42 | rubber_duck | but I'm not 100% on that It's been a long time since I mucked around with that |
| 16:42 | mdrogalis | justin_smith: Hah, cool :D |
| 16:43 | stuartsierra | Yes, vars have names, you can get it from their metadata as :name and :ns, then ns-name, … |
| 16:43 | rubber_duck | SagiCZ1, from the sound of what you're trying to do I'd say you would use a macro |
| 16:44 | SagiCZ1 | ,(def foo) |
| 16:44 | rubber_duck | (mymacro (foo ...) (bar ...)) -> expand in to {:foo (foo ...) :bar (bar ...)} |
| 16:44 | clojurebot | #'sandbox/foo |
| 16:44 | SagiCZ1 | ,(meta foo) |
| 16:44 | clojurebot | nil |
| 16:45 | SagiCZ1 | rubber_duck: sounds correct, but i am a macro virgin.. i bet i will do something wrong, forget some gensym or someting and my whole project literally explodes |
| 16:45 | justin_smith | ,(into {} (for [f [#'+ #'- #'* #'/]] [(keyword (:name (meta f))) (f 1 2)])) ; SagiCZ1 |
| 16:45 | clojurebot | {:+ 3, :- -1, :* 2, :/ 1/2} |
| 16:45 | justin_smith | rubber_duck: can be done without a macro ^ |
| 16:45 | SagiCZ1 | justin_smith: do i need those ugly hashmarks? |
| 16:46 | justin_smith | ,(= #'+ (var +)) |
| 16:46 | clojurebot | true |
| 16:46 | stuartsierra | SagiCZ1: What's wrong with writing {:foo (foo …) :bar (bar …)} ? |
| 16:46 | justin_smith | ,(into {} (for [f [(var +) (var -) (var *) (var /)]] [(keyword (:name (meta f))) (f 1 2)])) ; SagiCZ1 |
| 16:46 | clojurebot | {:+ 3, :- -1, :* 2, :/ 1/2} |
| 16:46 | justin_smith | stuartsierra: excellent point |
| 16:47 | SagiCZ1 | stuartsierra: i was just being lazy and curious |
| 16:47 | SagiCZ1 | thank you for help |
| 16:48 | stuartsierra | ;) |
| 16:52 | boblarrick | OK nevermind still stuck |
| 16:52 | boblarrick | how to flatten something like '((168 99) 68 (407 53 335) 158 (168 99)) ? |
| 16:53 | mearnsh | ,(flatten '((168 99) 68 (407 53 335) 158 (168 99))) |
| 16:53 | clojurebot | (168 99 68 407 53 ...) |
| 16:53 | justin_smith | boblarrick: how did it get that shape in the first place? |
| 16:53 | boblarrick | combo/cartesian-product |
| 16:55 | justin_smith | wait, clojure.math.combinatorics/cartesian-product mixes sequences and elements in its output? |
| 16:57 | dbasch | boblarrick: if your single elements were one-element lists you could do apply concat, but really you shouldn’t have created that output |
| 16:57 | justin_smith | boblarrick: anyway, the right way to deal with something like that isn't flatten, it's using something that gives you the shape of data you need and using it apropriately, because flatten can do bad things if any of the elements you are working with are themselves collections |
| 16:57 | boblarrick | /shrug |
| 17:00 | boblarrick | I've got millions of these things, and i need the generation and the flattening to be quick |
| 17:01 | boblarrick | worried doing things "the right way" might add overhead, that would add up to a runtime I can't tolerate |
| 17:01 | dbasch | ,(apply concat (map #(if (coll? %) % [%]) '((168 99) 68 (407 53 335) 158 (168 99)))) |
| 17:01 | justin_smith | flatten is not quick, apply concat would be quicker if the data format were consistent |
| 17:01 | clojurebot | (168 99 68 407 53 ...) |
| 17:02 | justin_smith | boblarrick: inconsistent data formats cause all code that interacts with them to be more complex, it can be a rippling effect that increases complexity throughout a codebase. Better to deal with it directly where the data is generated |
| 17:03 | boblarrick | this is where the data is generated |
| 17:03 | boblarrick | sorry I have to run, I'll benchmark some things and see what's u |
| 17:03 | boblarrick | up |
| 17:05 | dbasch | boblarrick: can you paste a gist/refheap with the code that generates the data |
| 17:05 | dbasch | ? |
| 17:05 | justin_smith | boblarrick: also, I have no idea how one gets combo/cartesian-product to output anything but sequences |
| 17:07 | justin_smith | dbasch: nice hack - better than flatten at least |
| 17:08 | boblarrick | https://www.refheap.com/92464 |
| 17:09 | boblarrick | dbasch: (map flatten) works as part of comp'ed transducer, didn't have similar luck with (apply concat (map irc://card.freenode.net:6667/#(if (coll? %) % [%]) |
| 17:09 | boblarrick | really gotta run, thanks for help! |
| 17:11 | justin_smith | so cartesian-product did not output any individual items, but it was asked to intermingle two element lists (cows) with three elements lists (foos) and single items (bars) |
| 17:11 | justin_smith | redefing bars would be enough to make a concat based solution work |
| 17:12 | justin_smith | (def bars [[:b] [:c] [:d]]) - then one can do consistent data operations on the result |
| 17:16 | dbasch | flatten really should be deprecated |
| 17:16 | dbasch | it probably causes more problems than it solves |
| 17:16 | amalloy | dbasch: (apply concat (map f xs)) is just (mapcat f xs) |
| 17:16 | dbasch | true |
| 17:16 | justin_smith | dbasch: it's a codependent partner to bad design |
| 17:18 | dbasch | mapcat is a very useful function, I usually remember it when I’m coding something from scratch |
| 17:18 | dbasch | I tend to think differently when I’m solving someone else’s problem for some reason |
| 17:20 | dbasch | I have yet to see a justifiable use of flatten though |
| 17:21 | dbasch | perhaps when parsing horrendous html? |
| 17:23 | dav_ | nick dav |
| 17:23 | justin_smith | dbasch: it could argubly be useful when using results apis that insist on turning every single element list into a single item with no list |
| 17:24 | justin_smith | dbasch: but once again, it's just a sign of bad design somewhere else |
| 17:25 | dbasch | reminds me of the tagline for nokogiri, an html parser for ruby |
| 17:25 | puredanger | ,(defn flatten' [s] (map (constantly '__) (flatten s))) |
| 17:25 | clojurebot | #'sandbox/flatten' |
| 17:25 | puredanger | ,(flatten' ['tomato (range 5)]) |
| 17:25 | clojurebot | (__ __ __ __ __ ...) |
| 17:25 | dbasch | “XML is like violence - if it doesn’t solve your problems, you are not using enough of it.” |
| 17:25 | justin_smith | lol |
| 17:25 | puredanger | see, I flattened it |
| 17:26 | puredanger | that's my new tag line, btw |
| 17:28 | danielszmulewicz | (inc puredanger) |
| 17:28 | lazybot | ⇒ 19 |
| 17:28 | danielszmulewicz | that's for making me laugh |
| 17:28 | puredanger | I shall treasure that inc |
| 17:28 | puredanger | ,(flatten' 'danielszmulewicz) |
| 17:28 | justin_smith | ,(defn flatten'' [s] (map #(symbol (apply str (map (constantly \_) (str %)))) (flatten s))) |
| 17:28 | clojurebot | #'sandbox/flatten'' |
| 17:28 | clojurebot | () |
| 17:28 | danielszmulewicz | Hey I disappeared instead... |
| 17:29 | justin_smith | ,(flatten'' '(daniel ((szmulewicz)))) |
| 17:29 | clojurebot | (______ __________) |
| 17:29 | puredanger | danielszmulewicz: forgot to make it seqable |
| 17:29 | puredanger | justin_smith: that should be called redact |
| 17:29 | justin_smith | good point |
| 17:30 | danielszmulewicz | I feel better. |
| 17:30 | danielszmulewicz | a bit flat |
| 17:31 | justin_smith | ,(defn carbonate [s] (map #(symbol (apply str (map (constantly `\') (str %)))) (flatten s))) |
| 17:31 | clojurebot | #'sandbox/carbonate |
| 17:31 | justin_smith | ,(carbonate '(daniel ((szmulewicz)))) |
| 17:31 | clojurebot | ('''''' '''''''''') |
| 17:31 | danielszmulewicz | that's worth an inc too |
| 17:31 | danielszmulewicz | (inc justin_smith) |
| 17:31 | lazybot | ⇒ 109 |
| 17:33 | danielszmulewicz | Does clojurescript has something like emit-string which compiles and hands over a string? |
| 17:34 | danielszmulewicz | Here's an example of what I'm after: (emit-string '(defn three+three [] (+ 3 |
| 17:34 | danielszmulewicz | 3)) |
| 17:35 | danielszmulewicz | Output should be: "ns.core.three_PLUS_three = |
| 17:35 | danielszmulewicz | (function three_PLUS_three(){return ((3) + (3)); |
| 17:36 | danielszmulewicz | Basically what emit does in cljs.compiler. |
| 17:36 | danielszmulewicz | where's dnolen? |
| 17:37 | justin_smith | danielszmulewicz: touring europe with his band last I heard |
| 17:37 | danielszmulewicz | justin_smith: oh, right! |
| 17:38 | danielszmulewicz | I saw the tweets. I had forgotten. |
| 18:04 | csd_ | I'm looking for some blog posts on best practices for managing code across developing locally, production server, etc. E.g. the fact that you want to juggle having one code base, but having to support different configurations for database server or what have you... anyone know of anything? |
| 18:05 | hiredman | the old standards are environment variables and configuration files |
| 18:05 | technomancy | use bcrypt |
| 18:05 | technomancy | oh wait, wrong meme |
| 18:05 | hiredman | there are libraries that deal with both, pick one and do that |
| 18:05 | technomancy | csd_: env variables are arguably simpler, but they can't handle nested values or really anything non-string. |
| 18:06 | technomancy | if you're on heroku, I recommend environ. otherwise carica. |
| 18:06 | csd_ | so basically i should create on my local comp and on the remote comp a path variable like PRODUCTION? and then if it's true do one things, and otherwise the other? |
| 18:06 | hiredman | https://twitter.com/hiredman_/status/527581910155800577 tweetsare basically blog posts, right? |
| 18:06 | technomancy | csd_: don't set PRODUCTION, set whatever it is you actually care about doing differently in production vs dev. |
| 18:06 | joshuafcole | csd_ We use node at my dayjob, but it's the same concept. We define a NODE_ENV=<key> |
| 18:06 | joshuafcole | where <key> is the key in an enumeration of available configurations |
| 18:07 | joshuafcole | including dev, stage, and prod |
| 18:07 | technomancy | I would recommend against bundling them up like that. |
| 18:07 | mdeboard | Anyone having issues with github atm |
| 18:07 | hiredman | https://github.com/sonian/carica is generally what we use at sonian (surprise) |
| 18:07 | hiredman | it uses configuration files over environment variables |
| 18:07 | technomancy | your provisioning tool should handle grouping configs, and your application should just read single values it cares about. |
| 18:07 | hiredman | and does some merging stuff |
| 18:07 | csd_ | why not just have a true/false env for development vs not, and then a config file with the different types of options depending on how the env var is set |
| 18:07 | mdeboard | hiredman, You work at Sonian eh? Your blog post on transitioning from backbone to react was a great help. |
| 18:08 | joshuafcole | You can, but it's a lot less flexible |
| 18:08 | csd_ | how so |
| 18:08 | puredanger | some people like the environ library to help with this stuff https://github.com/weavejester/environ |
| 18:08 | joshuafcole | What if you want to introduce an integration server? |
| 18:08 | joshuafcole | or a staging server? |
| 18:08 | joshuafcole | that has some of the features of dev and some of prod? |
| 18:08 | technomancy | csd_: why would you put production config on your dev machines? |
| 18:08 | hiredman | csd_: it depends on how many places you might deploy to |
| 18:08 | csd_ | gotcha |
| 18:09 | hiredman | csd_: for example at work we have dev, qa, ua, plus multiple production environments |
| 18:09 | csd_ | so when you guys are working on a project you stick those vars into your bash_rc? or is there a tool that manages them |
| 18:10 | joshuafcole | Depends on your deploy system. If it's flexible enough, you can have a single config that's provisioned by the deploy system |
| 18:10 | technomancy | csd_: for env vars I put the default value in the code and only set the env var to override it, but I don't feel great about it. |
| 18:10 | joshuafcole | a good middle ground is to have a set of control scripts for your applications in each environment that have the right env var baked in |
| 18:10 | technomancy | one big downside of env vars is you can't change them without restarting the JVM, which is super tedious. |
| 18:10 | joshuafcole | mhmm |
| 18:13 | technomancy | ideally you'd only set them in actual deployments and not in development, because everyone gets super confused about how to reliably set env vars in dev in ways that will work outside bash. |
| 18:13 | csd_ | puredanger: that library looks pretty useful |
| 18:14 | technomancy | environ might fix the change-without-restart problem; I forget |
| 18:16 | puredanger | well that's not an issue with java system properties |
| 18:16 | puredanger | and those are supported by environ, so there's probably options at least |
| 18:19 | technomancy | nice |
| 19:12 | EvanR | is there a thing where you can put (example (my-fun a b c) d) which does a sanity check/doc. assert? |
| 19:13 | {blake} | ,(println ["Y" "N"]) |
| 19:13 | clojurebot | [Y N]\n |
| 19:13 | {blake} | (map println ["Y" "N"]) |
| 19:13 | {blake} | ,(map println ["Y" "N"]) |
| 19:13 | clojurebot | (Y\nN\nnil nil) |
| 19:13 | {blake} | huh |
| 19:14 | justin_smith | {blake}: the output of println gets mixed with the return value of map |
| 19:14 | {blake} | justin_smith, Right. |
| 19:14 | justin_smith | ,(dorun (map println ["Y" "N"])) |
| 19:14 | clojurebot | Y\nN\n |
| 19:14 | justin_smith | I assume you would never need that list of nils |
| 19:15 | {blake} | justin_smith, No, it's the sort of thing that trips me up when I hit one thing I don't understand, then start inserting println to try to figure it out. |
| 19:16 | justin_smith | right :) |
| 19:16 | justin_smith | using a proper logger helps |
| 19:16 | {blake} | What would qualify as a proper logger? |
| 19:17 | justin_smith | {blake}: another trick I like is (defonce debug (atom [])) followed by various calls to (swap! debug conj [:descriptor value]) |
| 19:17 | {blake} | justin_smith, creates a running log of whatever you swap? |
| 19:18 | justin_smith | {blake}: right, and you can play with the data in the repl |
| 19:18 | justin_smith | {blake}: sometimes it helps because you can actually play with the values in the repl |
| 19:18 | justin_smith | but that's not a proper logger |
| 19:18 | justin_smith | it's just a technique I like |
| 19:18 | {blake} | *nod* |
| 19:18 | justin_smith | for a proper logger I would use tools.logging or timbre |
| 19:19 | {blake} | 'k. I'll have to check those out. |
| 19:19 | {blake} | So, I =think= I have a vector of ["Y" "N"]. But when I try to map I just get a LazySeq. |
| 19:20 | justin_smith | map returns lazyseqs... |
| 19:20 | justin_smith | ,(class (map identity [1 2])) |
| 19:20 | clojurebot | clojure.lang.LazySeq |
| 19:20 | justin_smith | ,(class (into (empty [1 1]) (map identity [1 2]))) |
| 19:20 | clojurebot | clojure.lang.PersistentVector |
| 19:21 | justin_smith | the problem with into / empty is it reverses the order of lists |
| 19:21 | justin_smith | but it preserves the type! |
| 19:21 | andrei | justin_smith: on the debugging atom, then you repeatedly ask for debug atom value after you do something? |
| 19:21 | utsc | hey guys, what is the transducer equivalent of "map<" from core.async? |
| 19:22 | justin_smith | andrei: I deref the debug atom in the repl, and do things with the data until I understand my bug |
| 19:22 | justin_smith | andrei: I also sometimes copy the data in said atom over into unit tests |
| 19:23 | andrei | justin_smith: but this is really nice :) I like that you could also take just a couple of items and inspect them instead of browsing through screens of logs |
| 19:24 | justin_smith | andrei: yes, I find it a very productive way to figure out what my code is doing while developing |
| 19:24 | {blake} | I'm trying to take a list and produce HTML, like (map #("<option>"%"</option>") l) and instead I'm getting back "lazySeq". |
| 19:24 | {blake} | Which is the sort of thing I thought I was beyond at this point. :/ |
| 19:24 | justin_smith | andrei: of course log still have their purpose (for example figuring out what is actually going on at runtime on the production server) |
| 19:25 | arrdem | {blake}: apply str? or just use hiccup :P |
| 19:25 | justin_smith | {blake}: apply str |
| 19:25 | justin_smith | (inc arrdem) |
| 19:25 | lazybot | ⇒ 38 |
| 19:25 | agarman | question re: java generics interfaces in reify; do I just ignore the parameterized portion of the interface when implementing reify because java generics are erased anyhow? |
| 19:25 | {blake} | arrdem, Yeah. I don't usually mix up apply and map these days. |
| 19:25 | justin_smith | yeah, no downside to just using hiccup |
| 19:25 | {blake} | And, yeah, I'm going to use hiccup. |
| 19:26 | justin_smith | agarman: yeah, generics are an illusion :) |
| 19:26 | arrdem | hiccup is pure awesome |
| 19:26 | justin_smith | or more precisely - a java compiler concept, and we are not using the java compiler |
| 19:26 | {blake} | I was just throwing up some output. |
| 19:26 | arrdem | for sure |
| 19:26 | justin_smith | {blake}: hope it's not ebola! |
| 19:26 | {blake} | Generics are part of the long war of statically typed languages against their type systems. |
| 19:27 | {blake} | justin_smith, badum-tish |
| 19:28 | justin_smith | ,(str (map inc (range 5))) ; {blake} |
| 19:28 | clojurebot | "clojure.lang.LazySeq@1c3e4a2" |
| 19:28 | justin_smith | ,(apply str (map inc (range 5))) ; {blake} |
| 19:28 | clojurebot | "12345" |
| 19:32 | {blake} | justin_smith, Yeah. My face is red. And not from the Halloween makeup. |
| 19:34 | justin_smith | (pr-str (map inc (range 5))) ; another option |
| 19:34 | justin_smith | ,(pr-str (map inc (range 5))) ; another option |
| 19:34 | clojurebot | "(1 2 3 4 5)" |
| 19:34 | justin_smith | pr-str produces better output for debugging |
| 19:35 | justin_smith | ,((juxt str pr-str) "a") |
| 19:35 | clojurebot | ["a" "\"a\""] |
| 19:35 | {blake} | Fair point. |
| 19:35 | {blake} | Ima use hiccup. |
| 19:35 | justin_smith | the pr-str differentiates a symbol from a string, str does not |
| 19:36 | {blake} | justin_smith, I've used it. Then forgot about it. |
| 19:37 | justin_smith | {blake}: reminds me of things I do :) |
| 19:38 | {blake} | justin_smith, It's been an amazing year spent with Clojure. I forgotten more than I've learned. Wait. |
| 19:47 | amalloy | oh boo, i just realized i actually do use C-z for things other than suspending. might need to find a new tmux prefix key |
| 19:48 | amalloy | C-c C-z to go to emacs's repl is just too hardwired into my fingers for me to train out of |
| 19:49 | justin_smith | emacs' repl as in ielm? |
| 19:49 | nwolfe | I like ` as my tmux prefix key |
| 19:49 | justin_smith | I thought I was the only one who ever used that |
| 19:50 | amalloy | justin_smith: no, slime, of course |
| 19:50 | justin_smith | heh |
| 19:50 | amalloy | nwolfe: that sounds horrific. don't you ever type a `? |
| 19:51 | nwolfe | amalloy: Haha it's not horrific - the few times I do need to actually enter a ` character I just press it twice |
| 19:54 | tuft | crazy to tire mentally because i'm back to little muscle memory |
| 19:54 | nwolfe | amalloy: I believe all I had to set were these 3 lines: https://github.com/nwolfe/dotfiles/blob/master/lib/tmux.conf.symlink#L78-L82 |
| 19:55 | amalloy | tuft: i forget, does it need two hands, or is there a one-handed way to do it? |
| 20:06 | justin_smith | wow, fascinating |
| 20:06 | justin_smith | the personal version duplicates qwerty |
| 20:06 | justin_smith | http://www.shareware-beach.com/2007/08/datahand-review/ |
| 20:08 | danielszmulewicz | This is a proof of concept to show how ClojureScript can be used in the context of Apple's JavaScript for Automation. https://gist.github.com/danielsz/9c4ed2fbf4c0ac6b2d95 |
| 20:08 | EvanR | is there a function to consume a seq and give the first non-nil value |
| 20:08 | justin_smith | EvanR: (first (filter (complement nil?) s)) |
| 20:09 | justin_smith | ,(some identity [nil false 3]) |
| 20:09 | dbasch | or (first (remove nil? s)) |
| 20:09 | clojurebot | 3 |
| 20:09 | justin_smith | ,(keep idenity [nil false 3]) |
| 20:09 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: idenity in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:10 | justin_smith | ,(keep identity [nil false 3]) |
| 20:10 | clojurebot | (false 3) |
| 20:10 | justin_smith | dbasch: yeah, that one is better :) |
| 20:13 | EvanR | i saw this identity function, is it the identity function? |
| 20:13 | EvanR | i guess the keep is relying on natural truthiness |
| 20:13 | justin_smith | EvanR: keep is like map, but it discards nils |
| 20:14 | EvanR | ok id still need first |
| 20:14 | justin_smith | yeah |
| 20:14 | justin_smith | if you don't want false, (some identity s) works |
| 20:14 | justin_smith | or you can just do (first (remove nil? s)) |
| 20:15 | EvanR | i need to distinguish between nil and false here |
| 20:15 | EvanR | so keep should work |
| 20:16 | EvanR | and im going the hell home |
| 20:21 | amalloy | EvanR: ☽ 263D FIRST QUARTER MOON? |
| 20:21 | technomancy | isn't that ... the werewolf key? |
| 20:21 | rpaulo | heh |
| 20:28 | justin_smith | 🌕 is the werewolf key |
| 20:30 | AeroNotix | could any one point me to where `try` is implemented? |
| 20:31 | justin_smith | ,(special-symbol? 'try) |
| 20:31 | clojurebot | true |
| 20:31 | technomancy | huh, TIL |
| 20:31 | justin_smith | that means somewhere in java I guess |
| 20:31 | technomancy | ,(:added (meta #'special-symbol?)) |
| 20:31 | clojurebot | "1.0" |
| 20:32 | justin_smith | technomancy: I found it via apropos because I wanted a way to know if something was a special form |
| 20:32 | justin_smith | I should do a "how to interrogate clojure" blogpost |
| 20:32 | technomancy | inc |
| 20:35 | justin_smith | I could do it all noir style. "So I'm sitting at my keyboard and up comes the most immutible lisp I've ever seen. Data structures up to here, concurrency like nobody's business" |
| 20:36 | AeroNotix | technomancy: yeah I was trying to see if I could write a slightly different try |
| 20:36 | AeroNotix | then I thought that it's going to be tricky since it has atypical syntax |
| 20:36 | justin_smith | of all the repls in this city, she just had to dump her stack trace into mine |
| 20:36 | technomancy | "the most immutable lisp I've ever seen" hehe |
| 20:37 | technomancy | AeroNotix: take a look at slingshot; it implements try+ |
| 20:39 | AeroNotix | technomancy: hm, I wanted to make the catch expression more like python's |
| 20:48 | justin_smith | AeroNotix: in what way? |
| 20:48 | AeroNotix | justin_smith: (catch (ExceptionA ExceptionB) e ... ) |
| 20:51 | justin_smith | AeroNotix: you could construct that with a macro, turining (my-try ... (catch [ExceptionA ExceptionB ExceptionC] e ...)) into (try ... (catch ExceptionA e ...) (catch ExceptionB e ...) (catch ExceptionC e ...)) |
| 20:51 | AeroNotix | justin_smith: that's what I am doing |
| 20:52 | justin_smith | Oh, OK then :) |
| 20:52 | AeroNotix | but getting the semantics of the built-in try is a bit different from a normal macro |
| 20:52 | AeroNotix | since you need to parse the body for the catch expression |
| 20:53 | justin_smith | isn't it treated like a lambda body? in what way do you need to parse it? |
| 20:53 | AeroNotix | justin_smith: because you need to know where to start looking for the list of Exception types |
| 20:54 | justin_smith | the source link on thie page is messed up https://clojuredocs.org/clojure.core/try |
| 20:55 | jeffterrell | Ah, you have to parse the body of the try expr to find where the catches begin. Is that it? |
| 20:56 | AeroNotix | jeffterrell: yeah |
| 20:56 | AeroNotix | I'm like half way done |
| 20:56 | justin_smith | if I was doing this, I would take the body as a list, map over it, operating on all nodes that start with the symbol catch |
| 20:57 | AeroNotix | that's what I am doing |
| 20:57 | AeroNotix | it's simpler than i thought |
| 20:57 | AeroNotix | but it's like 2am so I may leave this til tomorrow |
| 21:15 | arrdem | ambrosebs: I feel like I owe you an appology now :P |
| 21:15 | ambrosebs | arrdem: no you win the awesome award |
| 21:16 | justin_smith | ambrosebs: watching your latest strange loop talk right now, good stuff so far btw |
| 21:16 | arrdem | ambrosebs: seriously tho if I could get core.typed dispatch I'd put that shit on everything |
| 21:16 | ambrosebs | justin_smith: why thank you |
| 21:16 | arrdem | I suppose I owe you a few more PRs before I get to complain about limitations tho |
| 21:17 | ambrosebs | arrdem: it might happen during my PhD, I've entertained combining predicate dispatch and Typed Clojure with the Typed Racket ppl |
| 21:18 | ambrosebs | although that might quite be what you mean? |
| 21:18 | arrdem | ambrosebs: threw money at you once, 8/8 would do again |
| 21:18 | arrdem | ambrosebs: core.typed enabled predicate/patern matching dispatch would be totally awesome |
| 21:19 | ambrosebs | haha well it might happen again during the summer. My visa rules are pretty darn strict. |
| 21:19 | ambrosebs | but I still owe everyone a bunch of videos |
| 21:19 | ambrosebs | I guess that's what christmas break is for |
| 21:19 | arrdem | :D |
| 21:19 | ambrosebs | yea, PhD and moving country kind of happened... |
| 21:19 | ambrosebs | :P |
| 21:20 | arrdem | hehe odds are very good I'll manage to get out without a masters |
| 21:20 | arrdem | but I'll be back of one |
| 21:20 | ambrosebs | you're aiming for phd? |
| 21:21 | arrdem | probably not, but the sort of lang/compiler stuff I think is fun is masters or better territory |
| 21:21 | arrdem | so who knows. I sure don't yet |
| 21:22 | ambrosebs | well I hope you keep it in mind. you'd probably have a lot of fun |
| 21:24 | arrdem | I'm sure that being a grad/phd candidate would be more fun... my primary complaint against my undergrad is the non-cs/non-research work which I find really soul sapping. :/ |
| 21:24 | arrdem | also you're not the first person to tell me to stick around for a PHD. peer pressure alone may yet do it. |
| 21:24 | TEttinger | arrdem, you've got skills for sure. It would be great to see what you come up with as a researcher |
| 21:25 | TEttinger | ambrosebs, you're the main force behind Typed Clojure, is that right? |
| 21:25 | ambrosebs | TEttinger: that's me |
| 21:25 | TEttinger | it certainly looks good. |
| 21:25 | TEttinger | I haven't used it yet |
| 21:26 | arrdem | core.typed is good when you have some code you know mostly works and you want to really push types through and get assurance |
| 21:26 | AeroNotix | I found it incredibly annoying to use |
| 21:26 | arrdem | I've found that because there isn't type dispatch it tends to be a little heavyweight for exploratory use |
| 21:27 | AeroNotix | there's so much code out there that's untyped that you end up typing and then your code becomes a mismash of type specifiers and your real code |
| 21:27 | ambrosebs | it takes a while to figure out when to just give up type checking something. It can happen fairly often for certain types of code |
| 21:27 | AeroNotix | and then sometimes you need to change your code to make it more obvious to the type checker |
| 21:27 | ambrosebs | yep. That's a real problem at the moment because there's no runtime enforcement of types |
| 21:27 | arrdem | AeroNotix: yeah I've had a couple of those |
| 21:27 | AeroNotix | all in all -> don't care. |
| 21:28 | AeroNotix | Try it out if it works for you but for any non-trivial codebases you really ought to start off with core.typed instead of adding it in later. |
| 21:28 | AeroNotix | and even then the value is questionable. |
| 21:28 | arrdem | I mean... mad props to ambrosebs, for a project built by 1.01 undergrads it's awesome, it just needs more than one mans's worth of work. |
| 21:28 | justin_smith | ambrosebs: how well would core.typed and prismatic/schema work together? chocolate and peanut butter or ice cream and pickles? |
| 21:28 | ambrosebs | justin_smith: theoretically just fine. Right now, there's been no effort to figure out the details. |
| 21:29 | amalloy | (inc justin_smith) ; for lisp-noir |
| 21:29 | lazybot | ⇒ 110 |
| 21:29 | ambrosebs | in theory you could use core.typed to ensure you're writing the correct Schema contracts and actually using them in the right spots to prevent type errors |
| 21:29 | ambrosebs | the problem is core.typed doesn't understand schemas |
| 21:30 | ambrosebs | and I've been apologising for that for about a year |
| 21:30 | justin_smith | so there would be duplicate effort |
| 21:30 | ambrosebs | no I think core.typed should be able to read schema definitions automatically |
| 21:30 | justin_smith | by duplicate effort I mean describing the same thing to core.typed and to schema |
| 21:31 | justin_smith | making core.typed understand schemas would by a one time cost that eliminates that duplication I would think |
| 21:31 | ambrosebs | that's what I think. |
| 21:32 | ambrosebs | the problem is that if you have no static type annotations, functions arguments would always be inferred to have type Any statically |
| 21:32 | ambrosebs | because schemas get applied in the body |
| 21:32 | ambrosebs | so you wouldn't get as many static type errors as you might like, but they would be turned into runtime errors |
| 21:33 | justin_smith | I'm still finding my bearings with both schema and core.typed, thanks for the input |
| 21:35 | ambrosebs | unfortunately the biggest barrier to understanding Schemas is the map schema can have more than just keywords as keys |
| 21:35 | ambrosebs | {:a Int (optional :b) Boolean} |
| 21:35 | ambrosebs | HMaps in core.typed only allow keywords |
| 21:36 | ambrosebs | so there's some shuffling that needs to be done, as well as figuring out how much structural equality I want to encode in the type system |
| 21:37 | ambrosebs | I'd hope it's downhill from there? |
| 21:37 | ambrosebs | :) |
| 21:37 | ambrosebs | very optimistic |
| 21:37 | justin_smith | cool |
| 21:38 | ambrosebs | core.typed already understands merge/assoc etc, so that can be automated. |
| 21:38 | ambrosebs | which is actually a pretty cool thing |
| 21:39 | ambrosebs | being able to understand dynamically constructed contracts |
| 21:39 | justin_smith | nice |
| 21:39 | ambrosebs | *crosses fingers* |
| 21:40 | AeroNotix | justin_smith: https://github.com/AeroNotix/crap/blob/master/src/crap/exceptions.clj#L20-L36 |
| 21:40 | AeroNotix | despite it being 2AM (and now 2:30AM) I decided to give it a go |
| 21:40 | AeroNotix | there's probably a better way to do that. |
| 21:41 | justin_smith | AeroNotix: looks fairly solid |
| 21:42 | AeroNotix | bedtime |
| 21:42 | fairuz | Hi guys |
| 21:43 | justin_smith | AeroNotix: the usage of both mapcat and unquote-splicing is something I would take a second look at |
| 21:43 | fairuz | Normally what do you guys use to make things modular? Something like a database module, booking module etc? |
| 21:43 | justin_smith | fairuz: namespaces and functions |
| 21:43 | fairuz | Or is it not a practice in clojure? |
| 21:43 | fairuz | So all of them will be in the same project? |
| 21:43 | fairuz | Nothing like different package or something |
| 21:44 | fairuz | and module A add dependencies to module B, something along this way |
| 21:44 | fairuz | Just need some ideas on how to start off my first clojure project |
| 21:44 | justin_smith | fairuz: that's what namespaces are for |
| 21:45 | justin_smith | fairuz: using immutibility changes the game a bit, and the need for data hiding is reduced |
| 21:45 | justin_smith | so it's common to put multiple related functionalities in one namespace |
| 21:46 | ambrosebs | curious if anyone's ever been bitten by ArraySeq's in Clojure and ClojureScript being mutable if you change the underlying array? |
| 21:46 | fairuz | justin_smith: Ok got it |
| 21:47 | fairuz | Does we can have several files with the same namespaces? Or the namespace is tied with the file name? |
| 21:47 | justin_smith | namespaces should be reflected by the file name |
| 21:48 | amalloy | reiddraper: i don't think i ever mentioned it to you: i think you'd be interested to know i wrote a test.check generator for instances of Thrift schemas: https://github.com/amalloy/thrift-gen |
| 21:49 | justin_smith | ambrosebs: as I think I mentioned on twitter, I think the strong consensus is that it's something you just shouldn't be doing. |
| 21:49 | ambrosebs | justin_smith: right, that's assuming *you* are the one changing the array |
| 21:49 | amalloy | (which could be useful for anyone who works with thrift, even if you don't really care about test.check) |
| 21:49 | justin_smith | ambrosebs: though I could see an argument for having a warning / error if you can't prove the underlyign array does not escape scope of the immutible collection's creation |
| 21:50 | justin_smith | ambrosebs: well the "don't do that" would extend not just to mutating it, but using something visible for others to mutate |
| 21:50 | fairuz | justin_smith: ok got it. Thanks |
| 21:51 | justin_smith | ambrosebs: that would be nice actually, now that I think about it, to warn if you are constructing something immutible using a mutable basis that escapes that scope... |
| 21:52 | arrdem | ambrosebs: is this the aset on seq that's been floating around for a bit or is this a different case? |
| 21:52 | bbloom | ambrosebs: i think this is a cafe of "fast and loose reasoning is morally correct" |
| 21:52 | bbloom | you can do better type checking if you just assume it's actually immutable |
| 21:53 | ambrosebs | bbloom: sure I've come around to the pragmatics of it |
| 21:53 | mindbender1 | ,(bit-or 1 2 3 4) |
| 21:53 | clojurebot | 7 |
| 21:53 | bbloom | s/cafe/case |
| 21:53 | mindbender1 | ,(apply bit-or '(1 2 3 4)) |
| 21:53 | clojurebot | 7 |
| 21:53 | ambrosebs | ,(let [a (into-array [1 2 3]) p (seq a) _ (aset a 0 2)] p) |
| 21:53 | clojurebot | (2 2 3) |
| 21:53 | ambrosebs | arrdem: that one ^ |
| 21:53 | arrdem | ambrosebs: yep |
| 21:54 | ambrosebs | bbloom: we should be able to still build a sound gradual type system that assumes seqs are immutable in the static portion. |
| 21:54 | reiddraper | amalloy: woah that's neat |
| 21:54 | ambrosebs | we basically need to track array mutations in static code, and also ensure any foreign arrays are copied before they are made seqs. |
| 21:55 | reiddraper | amalloy: i should create a 'test.check libraries' thing on the readme or something |
| 21:55 | mindbender1 | sorry (apply bit-or '(1 2 3 4)) doesn't give the correct answer in cljs-repl. |
| 21:55 | arrdem | ambrosebs: is there a compelling reason to do that rather than declare the above an abstraction fault and unsupported? |
| 21:55 | mindbender1 | there's no way to replicate it here |
| 21:55 | amalloy | ,(doc bit-or) |
| 21:55 | clojurebot | "([x y] [x y & more]); Bitwise or" |
| 21:56 | ambrosebs | arrdem: yes, a gradual type system is designed to protect the typed code to preserve its soundness at all costs |
| 21:56 | bbloom | ambrosebs: would be cool if you could mark the array type as aliased to an immutable position, and then throw an error on future changes to it |
| 21:56 | justin_smith | arrdem: well, you could create something "immutible" from a mutible source by mistake, and get bugs later. I think the ability of static typing to detect that would be nice. |
| 21:56 | mindbender1 | amalloy: it doesn't work correctly in cljs-repl |
| 21:56 | ambrosebs | so even to protect someone passing an array from the Java API to clojure |
| 21:56 | bbloom | ambrosebs: but then of course i'm going to play devil's advocate and say that i want idempotent sets to be statically allowable ;-) |
| 21:56 | amalloy | mindbender1: what does it produce? |
| 21:57 | mindbender1 | it keeps producing 3 |
| 21:57 | mindbender1 | that is the first 2 |
| 21:57 | ambrosebs | bbloom: yes that's one direction my phd could go :) |
| 21:57 | ambrosebs | I'll dig into linear types next year probably |
| 21:57 | amalloy | mindbender1: the cljs version of bit-or doesn't accept multiple args |
| 21:57 | ambrosebs | bbloom: what do you mean by your last remark? |
| 21:57 | amalloy | it takes exactly two |
| 21:58 | ambrosebs | what is an idempotent set |
| 21:58 | bbloom | ,(let [a (into-array [1 2 3]) p (seq a) _ (aset a 0 1)] p) |
| 21:58 | clojurebot | (1 2 3) |
| 21:58 | mindbender1 | amalloy: but (bit-or 1 2 3 4) does the right thing |
| 21:58 | ambrosebs | oh right an aset :) |
| 21:58 | bbloom | ambrosebs: ^^ setting a[0] to 1 is totally safe to do |
| 21:58 | bbloom | heh yeah |
| 21:58 | bbloom | ambrosebs: i would love it if you figured out how to type check transients implementations |
| 21:58 | ambrosebs | that's just crazy |
| 21:58 | ambrosebs | yea! |
| 21:58 | bbloom | ambrosebs: i dunno if you saw my various twitter ramblings about it |
| 21:58 | ambrosebs | this all sounds related |
| 21:59 | ambrosebs | yes I did |
| 21:59 | ambrosebs | I think I briefly talked to samth about it offline. but I was despairing about mutable seqs at the time. |
| 22:00 | amalloy | mindbender1: i see. bit-or is implemented as a variadic macro, but there's also a function version of it which only accepts two args |
| 22:01 | amalloy | i'd say that's a bug: the function version should accept any number of args |
| 22:01 | mindbender1 | amalloy: is there a function I can use to work around that immediately |
| 22:01 | justin_smith | how well does cljs handle / reflect the laxity about argument count in js? |
| 22:02 | amalloy | mindbender1: (defn good-bit-or [& args] (reduce #(bit-or % %2) 0 args)) is probably fine |
| 22:02 | amalloy | justin_smith: not well |
| 22:02 | amalloy | if you call a function with too many args, the extras just fall on the floor |
| 22:03 | mindbender1 | amalloy: thanks it's working. I'd manage that for now! |
| 22:16 | Rakko | How can I make Clojure scripts into .exes instead of .dlls using Clojure-CLR? |
| 22:27 | justin_smith | Rakko: it looks like there was an unmerged patch for this (dunno if it really works) http://dev.clojure.org/jira/browse/CLJCLR-25 |
| 22:30 | justin_smith | Rakko: also, it looks like lein-clr generates exe files https://github.com/kumarshantanu/lein-clr |
| 22:30 | justin_smith | you could use that, or figure out how it does it I guess |
| 22:35 | hiredman | ugh, the way pprint prints out vars is just terrible |
| 22:35 | hiredman | every time I use it I cringe |
| 22:35 | amalloy | ,(clojure.pprint/pprint #'inc) |
| 22:35 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint> |
| 22:36 | Rakko | thanks, justin_smith ! |
| 22:36 | amalloy | ,(do (require 'clojure.pprint) (clojure.pprint/pprint #'inc)) |
| 22:36 | clojurebot | #<Var@107e78: #<core$inc clojure.core$inc@f278dd>>\n |
| 22:36 | justin_smith | (require '[clojure.pprint :as ugly-print]) |
| 22:38 | hiredman | is it not the worst? |
| 22:39 | justin_smith | I'd hate to see the representations that weren't chosen for vars |
| 22:39 | TimMc | It's ... just ... *awful*. |
| 22:39 | TimMc | [said in the voice of Cecil from Welcome to Night Vale] |
| 22:39 | amalloy | ,(str #'inc) |
| 22:39 | clojurebot | "#'clojure.core/inc" |
| 22:41 | hiredman | amalloy: what happens is vars aren't handled special they fall through to pprints deref handler |
| 22:42 | hiredman | you can actually work around it, but having to do it over and over every time you use it is not great |
| 22:49 | hiredman | http://dev.clojure.org/jira/browse/CLJ-1576 |
| 22:49 | hiredman | vote early, vote often |
| 22:51 | justin_smith | votd |
| 22:52 | Rakko | wow, there are at least two devins in the clojure world |
| 22:58 | Raynes | Two whole devins??????? |
| 22:59 | TimMc | What a deal! |
| 23:00 | justin_smith | Raynes: any big picture hints of where I would start with making lazybot use the new irclj? If not I'll just dive right in |
| 23:00 | TimMc | Raynes: I feel like I haven't seen you in forever. |
| 23:00 | Raynes | justin_smith: One moment sir. |
| 23:00 | Raynes | TimMc: I'm always around. :) |
| 23:01 | Raynes | I just only hop in periodically. I've been rather preoccupied for a while now. |
| 23:03 | justin_smith | Ran 0 tests containing 0 assertions. 0 failures, 0 errors. |
| 23:03 | justin_smith | :) |
| 23:03 | Raynes | justin_smith: https://github.com/Raynes/lazybot/blob/master/src/lazybot/irc.clj |
| 23:03 | Raynes | justin_smith: lazybot core is one thing, plugins are another. |
| 23:04 | justin_smith | Raynes: cool |
| 23:04 | Raynes | You'll probably break half the plugins no matter what you do. |
| 23:04 | justin_smith | that's a small namespace, promising |
| 23:04 | justin_smith | that's not promising |
| 23:04 | justin_smith | haha |
| 23:04 | justin_smith | I guess I may end up making some tests and or using schema for sanity's sake |
| 23:04 | Raynes | The important thing is to get the core connection stuff moved over, get the core plugin system using the new stuff |
| 23:05 | Raynes | lazybot was not well written enough for unit tests to be very useful for it. |
| 23:05 | Raynes | :P |
| 23:05 | Raynes | You can probably get a testing framework in there pretty easily though. |
| 23:05 | justin_smith | Raynes: this is someting I have dealt with before. I'll see how crazy it gets. |
| 23:06 | Raynes | Well, you can do testing plugins really easily,. |
| 23:06 | justin_smith | Raynes: it's an approach to code reading |
| 23:06 | Raynes | All you have to do is emulate the mechanism that calls the plugin system. |
| 23:06 | justin_smith | "I think I know what this does, now I'll write a test to prove / disprove that" - then attempt your fix and see how the test responds |
| 23:07 | justin_smith | Raynes: sounds about right, yeah |
| 23:07 | TimMc | Just use Spring's PluginSingletonAbstractDependencyInjectionEmulatorEngineFactory to do it. |
| 23:07 | Raynes | TimMc: I wrote a factory for the first time a few days ago. |
| 23:07 | justin_smith | TimMc: oh of course, why didn't I think of that |
| 23:07 | Raynes | In Python :3 |
| 23:08 | Raynes | TimMc: https://www.refheap.com/92467 |
| 23:08 | Raynes | Look at that shit. |
| 23:08 | Raynes | LOOK AT IT! |
| 23:09 | justin_smith | Raynes: man, if I squint my eyes I can see the conveyor belts and the little ladies with hair nets and latex gloves |
| 23:09 | Raynes | =D |
| 23:09 | Raynes | I used dropwhile for the first time in python today. |
| 23:09 | Raynes | Then realized getting the index of the item + using slicing was a better solution. |
| 23:10 | Raynes | Then I took a swig of rum and cried myself to sleep. |
| 23:10 | TimMc | Every time you write the word "factory" a mid-level manager gets their wings. |
| 23:14 | kenrestivo | http://xkcd.com/224/ |
| 23:14 | kenrestivo | s/perl/python/g |
| 23:17 | Raynes | kenrestivo: you okay bro |
| 23:18 | kenrestivo | doing well. laffing at your riffs on python factories etc |
| 23:23 | Raynes | kenrestivo: I made some tunes recently. Didn't even listen to them for quality. Sending them to you for approval. :P |
| 23:23 | kenrestivo | my god, this whole town just went berserk |
| 23:24 | Raynes | Oh the sportsball |
| 23:31 | chenglou | how is clojure's = implemented for collections? |
| 23:31 | chenglou | does it just compare the hashes? |
| 23:31 | TimMc | kenrestivo: Did the local sports team sports hard enough, or not hard enough? |
| 23:31 | chenglou | and always fast? |
| 23:31 | Raynes | TimMc: In PM he described it as cheering. |
| 23:32 | TimMc | Oh good! |
| 23:32 | Raynes | I think that means the local sportsball team did well. |
| 23:32 | Raynes | At sportsball. |
| 23:32 | Raynes | Dunno about the rest of their lives. |
| 23:32 | Raynes | But the sportsball they've solidly done well |
| 23:32 | chenglou | also is there any blog post explaining how the hashing is done efficiently |
| 23:32 | kenrestivo | if people got this excited about $thing_that_actually_matters, we'd have all the world's problems solved |
| 23:32 | TimMc | I'm sure they will make good decisions. |
| 23:33 | TimMc | chenglou: That's actually a really good question! |
| 23:33 | justin_smith | chenglou: it first checks for object identity, then structural equality iirc. Something to look at is hasheq as puredanger mentions here http://stackoverflow.com/questions/26622511/clojure-value-equality-and-sets |
| 23:34 | justin_smith | chenglou: because if the args are literally the same object, there's no need to go deeper, of course |
| 23:36 | chenglou | justin_smith: how is the structural equality comparison done? Just naive comparison? |
| 23:37 | justin_smith | chenglou: best to check the source at that point I would say |
| 23:37 | chenglou | kk. I guess I shouldn't be worrying about perf this early on but for some random experiments I have to compare large quantities of collections against others (freshly created, no structural sharing). I was wondering if the magic of clojure's hashing could make this not slow |
| 23:38 | justin_smith | chenglou: well, if nothing is shared I don't know of any alternative that wouldn't involve walking every collection at least once |
| 23:40 | chenglou | right, but if the hash's already produced beforehand then this isn't a problem |
| 23:40 | justin_smith | chenglou: well, hash can only tell you there isn't a match |
| 23:40 | chenglou | also interested in knowing the collision rate |
| 23:40 | justin_smith | if it's the same hash, you still need to walk and double check |
| 23:40 | justin_smith | it just rules out possibilities, it doesn't mark them |
| 23:40 | chenglou | true... |
| 23:41 | justin_smith | chenglou: puredanger could probably help you more than I but he seems not to be around, but I assume most of your answers sit in this directory here: https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang |
| 23:43 | justin_smith | Raynes: youre readme mentions ".lazybot/info.clj" - do you have an example or template for that file? |
| 23:43 | Raynes | lol my readme |
| 23:43 | Raynes | My readme last updated when I was 12 or something |
| 23:43 | justin_smith | heh |
| 23:43 | chenglou | thanks |
| 23:43 | amalloy | justin_smith: it's config.clj now, iirc. should be one of those in the project root or thereabouts |
| 23:44 | justin_smith | Raynes: is it related to config.clj |
| 23:44 | justin_smith | oh, got it |
| 23:44 | justin_smith | lol |
| 23:44 | Raynes | justin_smith: It probably *is* confi |
| 23:44 | Raynes | Oh hi amalloy |
| 23:44 | Raynes | justin_smith: So amalloy apparently knows more about this bot than I do at this point. |
| 23:44 | Raynes | Discouraging. |
| 23:44 | justin_smith | Raynes: awesome, I have my first edit going in right now (to the readme) :) |
| 23:45 | amalloy | Raynes: 683 commits / 145,375 ++ / 7,850 --; amalloy: 170 commits / 5,848 ++ / 5,387 -- |
| 23:45 | amalloy | i wonder how on earth you found 145k lines to add |
| 23:45 | Raynes | I worked hard |
| 23:46 | justin_smith | a very particular coding style: (\ndefn\nfoo\n[\narg\narg2\n...]\n...\n) |
| 23:46 | bbloom | wtf? `lein repl` is OOM-ing on a random project of mine now |
| 23:53 | bbloom | does anybody have any ideas why i'm getting OutOfMemoryError when trying to run `lein repl` on a pretty simple project? |
| 23:53 | bbloom | it happens during startup, before the repl is ready |
| 23:54 | justin_smith | bbloom: ick - bad plugin interaction? middleware bug? |
| 23:54 | bbloom | this project has no plugins or middleware |
| 23:54 | bbloom | git on my dotfiles says i haven't changed my profiles.clj in 2 weeks |
| 23:54 | justin_smith | and nothing coming in from profiles.clj that would interact badly with that project.clj? |
| 23:54 | bbloom | this project worked a few days ago |
| 23:54 | justin_smith | oh |
| 23:55 | justin_smith | snapshot in the deps tree? |
| 23:56 | bbloom | only one snapshot, and it's something that shouldn't be in any public repos, so it shouldnt' have changed |
| 23:56 | Raynes | bbloom: Are you by chance on a raspberry pi? |
| 23:56 | justin_smith | I guess you could turn on heap dumps and analyze the dump in a profiler |
| 23:56 | bbloom | Raynes: sometimes my mac feels as slow as a raspberry pi |
| 23:57 | Raynes | bbloom: lol you should try a raspberry pi |
| 23:57 | Raynes | I nearly tied compiling deps for a python project once |
| 23:57 | Raynes | died, even |
| 23:58 | chenglou | justin_smith: TimMc seems like it's just plain item-by-item comparison |