2016-04-05
| 00:01 | tolstoy | Not (str (System/getenv "HOME") java.io.File/separator ".stuff.edn"))? ;) |
| 00:01 | tolstoy | (str (System/getProperty "user.home") java.io.File/separator ".stuff.edn")) |
| 00:02 | cwgem|mac | If there's a Java way (like what appears to show up there) to get home I'd probably use that versus trying to work with raw environment variables |
| 00:04 | sdegutis | bbl |
| 00:52 | user__ | man |
| 00:52 | user__ | everytime |
| 00:52 | user__ | nil, nil, nil |
| 00:52 | user__ | args |
| 00:53 | user__ | TEttinger, I'm havinga brain fart |
| 00:53 | tolstoy | Mapping println over values? |
| 00:56 | TEttinger | eh? |
| 00:57 | TEttinger | yeah tolstoy likely has it |
| 00:57 | TEttinger | print returns nil |
| 00:57 | TEttinger | same with println, prn, pr, pprint |
| 00:57 | TEttinger | there's pr-str |
| 00:57 | TEttinger | which returns a string version of what pr would print, but doesn't print on its own |
| 00:57 | tolstoy | The other one is some version of (map (when test :val) ...). |
| 00:57 | TEttinger | ,(pr-str (map inc [1 2 3])) |
| 00:58 | clojurebot | "(2 3 4)" |
| 00:59 | user__ | TEttinger, tolstoy could be a print |
| 00:59 | TEttinger | cwgem|mac: I think clojure may still have trouble with so-called "astral plane" values outside the Basic Multilingual Plane |
| 00:59 | TEttinger | like emoji chars, cwgem|mac |
| 00:59 | user__ | but my printing is also print nil |
| 00:59 | user__ | I feel like I'm so close to getting Clojure |
| 00:59 | user__ | i'm very new to lisp |
| 00:59 | user__ | but learning fast |
| 01:00 | cwgem|mac | TEttinger: Not too worried about emoji yet. Just need it to be able to handle CJK |
| 01:00 | user__ | ,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (count (:paths(nth listInput 1))))) |
| 01:00 | clojurebot | 2 |
| 01:00 | TEttinger | it seems like you're getting there. you understand that there's no "void" returns in Clojure, right user__? |
| 01:00 | user__ | oh |
| 01:00 | user__ | thats not it |
| 01:00 | TEttinger | something like Java's |
| 01:00 | user__ | TEttinger, i guess |
| 01:00 | user__ | TEttinger, what if an empty function is used |
| 01:01 | TEttinger | ,(.println System/out "yay") |
| 01:01 | clojurebot | nil |
| 01:01 | TEttinger | print is wrapped specially in clojurebot |
| 01:01 | TEttinger | System.out in Java isn't normally used to print in clojure, so clojurebot just shows what it returns |
| 01:01 | user__ | ,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (nth (:paths(nth listInput 1)))0)) |
| 01:01 | clojurebot | #error {\n :cause "Wrong number of args (1) passed to: core/nth"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/nth"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 32]\n [sandbox$eval97 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval97 invo... |
| 01:01 | TEttinger | ah, that's dense |
| 01:02 | TEttinger | ,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (nth (:paths(nth listInput 1))0))) |
| 01:02 | clojurebot | [:node 2 :cost 1] |
| 01:02 | user__ | ,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (nth (:paths(nth listInput 1))0))) |
| 01:02 | clojurebot | [:node 2 :cost 1] |
| 01:02 | TEttinger | heh |
| 01:02 | user__ | beat me to it |
| 01:02 | user__ | ,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (:node(nth (:paths(nth listInput 1))0)))) |
| 01:02 | clojurebot | nil |
| 01:02 | user__ | there |
| 01:02 | user__ | nil |
| 01:02 | user__ | that freaking nil |
| 01:02 | user__ | ugh |
| 01:03 | TEttinger | oh! |
| 01:03 | user__ | ,clojurebot, what is this wizardry? |
| 01:03 | clojurebot | #error {\n :cause "Unable to resolve symbol: clojurebot in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: clojurebot in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: clo... |
| 01:03 | user__ | ok thanks |
| 01:03 | TEttinger | ,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (nth (:paths(nth listInput 1))0)) |
| 01:03 | clojurebot | [:node 2 :cost 1] |
| 01:03 | TEttinger | so that's what you are trying to call :node on |
| 01:03 | user__ | yes |
| 01:04 | TEttinger | but that isn't a map, it's a vector |
| 01:04 | TEttinger | maps use {} |
| 01:04 | TEttinger | vectors use numbers for keys |
| 01:04 | TEttinger | like arrays, but resizable |
| 01:04 | TEttinger | I suspect you had that as a map at some point |
| 01:05 | user__ | oh |
| 01:05 | TEttinger | ,(let [listInput [{:paths [[:node 1, :cost 1], [:node 2, :cost 2]]},{:paths [[:node 2, :cost 1], [:node 3, :cost 2]]},{:paths [[:node 0 :cost 1], [:node 1, :cost 2]]}] ] (print (:node(apply hash-map (nth (:paths(nth listInput 1))0))))) |
| 01:05 | clojurebot | 2 |
| 01:05 | user__ | wow |
| 01:06 | user__ | that was cool |
| 01:06 | TEttinger | thankfully, maps are really easy to make in clojure compared to Java |
| 01:06 | user__ | you got the :node in there |
| 01:06 | TEttinger | yep! |
| 01:06 | user__ | Yes, java maps are terrible |
| 01:06 | user__ | way too messy |
| 01:06 | user__ | java should possibly stick with linked list or arrays lol |
| 01:07 | TEttinger | Clojure makes them a lot better, so even though they extend Java's Map interface and that means they aren't considered Collections (which is silly), Clojure lets you call seq on a hash-map or other map as a special case |
| 01:07 | TEttinger | and since seq works, map works (operating on key-value pairs) |
| 01:08 | TEttinger | and a lot of other stuff Just Works because of seq |
| 01:10 | TEttinger | ,(map (fn [[k v]] (+ k v)) {1 10, 2 20, 3 30}) ;; the extra square brackets inside the fn arg vector mean it's "destructuring" the argument it gets, turning the two elements of a seq-like thing it's passed into two named values, k and v (corresponding to the key and value) |
| 01:10 | clojurebot | (11 22 33) |
| 01:11 | TEttinger | destructuring also makes maps much easier to work with |
| 01:11 | TEttinger | in addition to other collections! |
| 01:13 | user__ | interesting |
| 01:13 | TEttinger | user__: next time you're stuck in a deeply nested piece of code like that, try removing the parts that are related to any errors you get. if you don't know, try removing outer calls that do things first (so not let, since you usually need the let in examples like you gave, but I removed the "(print (:node" part and the parens on the other side |
| 01:14 | TEttinger | so you can try removing layers like peeling an onion, seeing if you need them first |
| 01:14 | user__ | TEttinger, Yes, i love this about Lisp |
| 01:14 | user__ | TEttinger, Makes function tracing easy |
| 01:15 | user__ | TEttinger, but i still need to get my head around sequences, vectors, maps, coll, and the rest |
| 01:15 | user__ | i get vectors and maps now which is great |
| 01:16 | user__ | I'm considering takingmy vector I had upon and changing the multiple vectors into a map |
| 01:17 | user__ | or sorry, changing the key values inside to use a map, but i don't want it cluttered either. |
| 01:21 | TEttinger | sure! that's a good idea |
| 01:35 | user__ | ,(let [listInput [{:paths [{:node 1}, {:cost 1}], [{:node 2}, {:cost 2}]]},{:paths [{:node 2}, {:cost 1}], [{:node 3}, {:cost 2}]},{:paths [{:node 0} {:cost 1}], [{:node 1} {:cost 2}]]}]] (print (:node(nth (:paths(nth listInput 1))0)))) |
| 01:35 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]> |
| 01:36 | user__ | ,(let [listInput [{:paths [[{:node 1}, {:cost 1}], [{:node 2}, {:cost 2}]]},{:paths [[{:node 2}, {:cost 1}], [{:node 3}, {:cost 2}]]},{:paths [[{:node 0} {:cost 1}], [{:node 1} {:cost 2}]]}]] (print (:node(nth (:paths(nth listInput 1))0)))) |
| 01:36 | clojurebot | nil |
| 01:36 | user__ | TEttinger, |
| 01:38 | TEttinger | oh! |
| 01:38 | user__ | nil is happening again :9 |
| 01:38 | user__ | :( |
| 01:38 | TEttinger | I know why |
| 01:40 | TEttinger | ,(let [listInput [{:paths [{:node 1, :cost 1}, {:node 2, :cost 2}]},{:paths [{:node 2, :cost 1}, {:node 3, :cost 2}]},{:paths [{:node 0, :cost 1}, {:node 1, :cost 2}]}]] (print (:node(nth (:paths(nth listInput 1))0)))) |
| 01:40 | clojurebot | 2 |
| 01:40 | TEttinger | you were converting individual pairs to maps |
| 01:40 | TEttinger | ,(apply hash-map [[:a 1] [:b 2]]) |
| 01:40 | clojurebot | {[:a 1] [:b 2]} |
| 01:40 | TEttinger | hm |
| 01:41 | TEttinger | ,(into {} [[:a 1] [:b 2]]) |
| 01:41 | clojurebot | {:a 1, :b 2} |
| 01:41 | TEttinger | there we go |
| 01:41 | TEttinger | I changed it by hand in the data because it seemed easy enough (it took longer than I thought though!) |
| 01:43 | user__ | ah |
| 01:43 | user__ | it makes sense ! |
| 01:43 | user__ | A map carries multiple key value pairs |
| 01:43 | user__ | aha! |
| 01:43 | user__ | i got it |
| 01:43 | user__ | thank you TEttinger |
| 02:15 | wombawomba | So I want to run a small, profile-dependent piece of code when any lein task runs, that sets some state in my application. As far as I can tell, I would have to write a custom leiningen plugin to do this. Does anyone know of an easier way? |
| 02:20 | tolstoy | One way is to use boot, which is much more scripty and imperative. |
| 02:20 | tolstoy | There used to be a way to do hooks (robert hooke library). |
| 02:21 | tolstoy | What do you want the code to do? |
| 02:27 | tolstoy | wombawomba: Here's something: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#hooks, but maybe a bash script might work better? |
| 02:50 | dysfun | or a makefile |
| 03:01 | kwladyka | wombawomba but if you only set state in the app, so i guess for example another date to database you can do it in lein. |
| 03:02 | wombawomba | sorry |
| 03:02 | kwladyka | ? |
| 03:03 | wombawomba | tolstoy: I want the code to set ips/ports for a bunch of hosts my project talks to |
| 03:03 | kwladyka | wombawomba maybe you need just that https://github.com/weavejester/environ ? |
| 03:04 | wombawomba | kwladyka: sorry, how do you mean about date to database? don't understand |
| 03:04 | clojurebot | Huh? |
| 03:04 | kwladyka | wombawomba ok i didn't guess your intention |
| 03:04 | wombawomba | and yeah, I guess environ could work |
| 03:05 | wombawomba | thanks |
| 03:05 | wombawomba | although, if I go with environ, I'd still have to make sure the init code is called for every target manually |
| 03:06 | wombawomba | eg I'd have to find some way to make my test runner call something like `(my-init-fn (env :profile))` before running any code |
| 03:07 | kwladyka | for tests use fixtures |
| 03:07 | wombawomba | I also have a bunch of aliases on the form run -m ... (essentially scripts), that would all have to call that code as well |
| 03:08 | wombawomba | kwladyka: I want to be able to run the exact same tests against a number of different host/ip configurations |
| 03:08 | wombawomba | but only one at a time |
| 03:08 | wombawomba | I don't think fixtures are appropriate, really |
| 03:08 | renl | hi in manifold is there a way to check if a stream has to take! from? |
| 03:08 | kwladyka | maybe you need profiles in the project.clj ? |
| 03:09 | wombawomba | kwladyka: yeah, that's what I'd like to do ideally |
| 03:09 | kwladyka | wombawomba https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md |
| 03:09 | wombawomba | I would like to have a bunch of profile, where each profile calls `(my-init-fn :profile-name)` as a first step for any task |
| 03:10 | wombawomba | kwladyka: afaict, there's no way to do that with profiles |
| 03:10 | wombawomba | I can do it for the repl, e.g. by setting :repl-options > :welcome |
| 03:10 | wombawomba | but I can't make sure it happens for my test runner, or for any of my `run -m ...` aliases |
| 03:12 | kwladyka | lein with-profile foo test don't satisfy you? I am not sure what is your problem :) |
| 03:12 | wombawomba | kwladyka: how do I get lein with-profile foo to run `(my-ns/my-init-fn :foo)` before the tests are run? |
| 03:13 | kwladyka | wombawomba use fixtures |
| 03:13 | wombawomba | and how do I get `lein with-profile foo run` to run `(my-ns/my-init-fn :foo)` before it calls main? |
| 03:13 | wombawomba | kwladyka: use fixtures how? |
| 03:14 | kwladyka | wombawomba something like that http://stackoverflow.com/questions/16350504/clojure-how-to-use-fixtures-in-testing |
| 03:14 | wombawomba | right |
| 03:14 | kwladyka | but i guess you can find better examples |
| 03:14 | wombawomba | but how do I run a fixture depending on which profile is active? |
| 03:15 | kwladyka | wombawomba you can use environ BTW and in fixtures read that value and depend on that value set something |
| 03:16 | wombawomba | yeah, if I use environ I can make it work |
| 03:16 | wombawomba | but I still have to manually make sure the proper code is called for every lein task, which is troublesome |
| 03:17 | wombawomba | I'd have to 1. do this in every fixture, 2. do this for the repl, 3. do this in every main- function I have |
| 03:18 | wombawomba | I am wondering if there's a way to do it once, in one place, without having to solve the problem in a different way for every lein task |
| 03:18 | kwladyka | i believe there is but don't solve everything at once time :) |
| 03:19 | kwladyka | you can use high priority functions or other solutions |
| 03:19 | kwladyka | to solve 3 |
| 03:19 | kwladyka | and also 1 |
| 03:20 | kwladyka | 2, i guess in the REPL you want start with clear enviroment |
| 03:20 | kwladyka | anyway maybe you solve your solution in bad way |
| 03:21 | kwladyka | for example maybe you should load different config files depend on profile, or depend your conf on the variable in the system like MY_VARIABLE_FOR_SETTING in the bash |
| 03:22 | kwladyka | many solutions are possible, but i don't know precisely your problem. You have to find your own way :) |
| 03:22 | wombawomba | :) okay |
| 03:22 | wombawomba | I think I'll try boot |
| 03:24 | kwladyka | wombawomba try it, but i believe the problem is in solution design what you try to do. |
| 03:24 | kwladyka | (but i can be in mistake, because i don't know details) |
| 03:25 | wombawomba | yeah, it's possible |
| 07:16 | Glenjamin | does anyone else find it really hard to read (> x y) vs (< y x) ? |
| 07:17 | ridcully | > and < in prefix notation don't work well with my brain |
| 07:18 | Glenjamin | i find < works ok, because you then write the arguments in ascending order |
| 07:18 | MJB47 | i 100% of the time |
| 07:18 | MJB47 | get them in the wrong order |
| 07:18 | Glenjamin | i just did exactly that |
| 07:18 | MJB47 | even if i know im going to get them in the wrong order, so purposely flip them around |
| 07:18 | MJB47 | they will still be in the wrong order |
| 07:21 | dmsnell | Glenjamin: confused me until someone said "it's always the same, just move the operator for infix in between the arguments" |
| 07:21 | dmsnell | (< 4 5) => (4 < 5) |
| 07:21 | dmsnell | (> 5 4) => (5 > 4) |
| 07:22 | ridcully | yeah, that's what i do. but it's basically the only operator i have such trouble with |
| 07:22 | mrcnxs | Glenjamin, so if y was greater than x would you write (< x y)? and if it wasnt you'd write (< y x)? and what if you didnt know what x or y was? |
| 07:22 | Glenjamin | i still know what i want to do |
| 07:22 | dmsnell | I would argue that you should use whichever is closer to indicating what you want to infer in the code |
| 07:23 | mrcnxs | dmsnell, yeah thats usually how it works |
| 07:23 | dmsnell | (if (> x y) (biggerX) (notBiggerX)) |
| 07:27 | Glenjamin | i just think that visually `<` looks like it's describing a little funnel |
| 07:27 | Glenjamin | and `>` looks like it's pointing at some numbers |
| 07:28 | mrcnxs | just think of < looks like L for less |
| 07:28 | dmsnell | Glenjamin: try (funnel 4 5) and (point-to-> 4 5) XD |
| 07:28 | ridcully | maybe time to alias them with gt, lt, gte, ... ;_ |
| 07:29 | tdammers | idk, I think < and > are bad names for variadic comparison functions, especially in prefix notation |
| 07:29 | tdammers | if you write a < b, it's obvious that you want the thing on the smaller end of the < to be smaller, but (< a b c) requires a mental leap |
| 07:30 | Kneiva | What do I need to import to use predicates like 'in' and 'like' in Korma SQL? |
| 07:30 | Glenjamin | (def ascending? <) |
| 07:31 | tdammers | Glenjamin: yeah, except that (ascending? a b) also requires a mental leap when what you really want to express is "a is less than b" |
| 07:35 | Glenjamin | also true |
| 08:16 | sdegutis | Good evening. |
| 08:20 | Glenjamin | morning |
| 08:20 | Glenjamin | is there a variant of cond/condp where I can pass a single argument and a series of predicates? |
| 08:22 | TimMc | Glenjamin: condp, if your argument is #(% foo bar) |
| 08:22 | Glenjamin | oh of course, that'll do it |
| 08:22 | TimMc | or hmm, maybe that's not quite it... |
| 08:22 | Glenjamin | thanks |
| 08:22 | Glenjamin | i get the gist |
| 08:22 | TimMc | I don't use condp very often. |
| 08:23 | luma | (condp #(%1 %2) expr pred-1 result-1 pred-2 result-2 ...) |
| 08:23 | Glenjamin | yup, thats the one |
| 08:24 | luma | that'll evaluate (pred-1 expr), and if it's truthy, return result-1 etc |
| 08:24 | Glenjamin | much nicer: https://www.refheap.com/116924 |
| 08:24 | TimMc | If all of your predicates are unary that could be annoying. |
| 08:24 | sdegutis | Glenjamin: what does your desired code look lik-- oh |
| 08:24 | TimMc | ah yeah, that works |
| 08:24 | Glenjamin | i was using normal (cond), but i'd forgotten to include the `number` argument with the sets |
| 08:24 | Glenjamin | so it was always matching the second clause |
| 08:24 | sdegutis | Glenjamin: hmm it seems like there really ought to be a pre-made macro for that |
| 08:25 | sdegutis | ive wanted that too |
| 08:25 | sdegutis | (condf) or something |
| 08:25 | TimMc | You forgot :VR, vice-regent |
| 08:25 | sdegutis | (condf x, pos? :positive, neg? :negative, zero? nil, :else (throw)) |
| 08:26 | sdegutis | justin_smith, TimMc, TEttinger3: does something like my conf exist? |
| 08:26 | sdegutis | *condf |
| 08:27 | ridcully | also you could cheat with your 42 numbered card ;) |
| 08:28 | Glenjamin | there's a (card) fn with some preconditions |
| 08:29 | Glenjamin | I'm prepping a functional version of http://buildingskills.itmaybeahack.com/book/oodesign-3.1/html/blackjack/details.html for a workshop at the local FP group |
| 08:29 | hyPiRion | sdegutis: (defmacro condf [& body] `(condp #(%1 %2) ~@body)) ? |
| 08:29 | hyPiRion | Except you must omit :else |
| 08:30 | sdegutis | hyPiRion: hmm sounds right, but it seems like such a useful thing that im surprised it doesnt already exist |
| 08:31 | Glenjamin | it would be possible to check for an odd number of arguments and generate :else I think |
| 08:31 | hyPiRion | condp #(%1 %2) isn't that much longer than condf |
| 08:31 | Glenjamin | https://github.com/glenjamin/defshef-blackjack/blob/master/clojure/src/defshef/blackjack.clj if anyone is interested in the rest |
| 08:31 | hyPiRion | Glenjamin: condp already does that |
| 08:31 | hyPiRion | ,(condp #(%1 %2) 2 odd? :odd :even) |
| 08:31 | clojurebot | :even |
| 08:31 | Glenjamin | aha |
| 08:32 | Glenjamin | oh i see what you mean about omitting now |
| 08:32 | Glenjamin | oh, that also means my :else is wrong |
| 08:33 | sdegutis | :) |
| 08:35 | Glenjamin | oh, heh - it works either way |
| 08:35 | Glenjamin | because the (throw) evals |
| 08:35 | Fender | Hi guys, I'm working with emacs/cider and I currently have the problem that after some changes to the code and C-c C-k my code changes are compiled successfully but they are not seen by the nrepl server. There are no changes to var/ns names and no indirections apart form a #'handler indirection due to being a ring app. Does anyone experience something similar? and is it a cider or a clojure 1.8 problem (-> invokeStatic) |
| 08:36 | Fender | my workflow now requires often a cider-restart and that's annoying |
| 08:42 | sdegutis | Fender: im using clojure 1.8 and cider 11, and dont have that problem |
| 08:42 | sdegutis | Fender: i think the reason i dont see the same problem you see is because i dont use vars (e.g. #'handler) but instead i re-build the handler from a function after cider-refresh |
| 08:43 | cwgem|mac | Any folks toyed around with Clojure on Java 9 EA out of curiosity? |
| 08:43 | Fender | to be honest, I am not entirely sure what cider-refresh does and for what it is useful (other than what the name suggests) |
| 08:44 | sdegutis | Fender: it's basically just a wrapper around tools.namespace.repl.refresh or whatever its claled |
| 08:44 | sdegutis | Fender: it re-evals all your changed files in dependency-order and then optinoally calls a function you tell it to |
| 08:45 | sdegutis | in my case, system-start |
| 08:45 | Fender | sounds like something I should be using in these cases |
| 08:47 | Fender | OK, I think I found something re the how and why: https://github.com/clojure/tools.namespace |
| 08:47 | Fender | thanks already |
| 08:48 | sdegutis | Fender: also read about stuartsierra's Reloadable Workflow |
| 08:48 | sdegutis | it inspired me to adjust my code to be more reloadable |
| 08:48 | sdegutis | which is hecka aweasome |
| 08:48 | Fender | where everything is saved in a context map? |
| 08:48 | Fender | I know about it but I didn't yet need it |
| 08:49 | Fender | well, I think I need to catch up on that :) |
| 08:54 | sdegutis | Fender: :) |
| 08:54 | sdegutis | hi all |
| 08:54 | sdegutis | how do you interpolate strings into a regex? |
| 08:54 | sdegutis | ,(let[foo"bar"]#"#{foo}") |
| 08:54 | clojurebot | #<NoClassDefFoundError java.lang.NoClassDefFoundError: Could not initialize class java.util.regex.PatternSyntaxException> |
| 08:55 | sdegutis | oh, re-pattern |
| 08:55 | sdegutis | ,(let[foo"bar"]#(re-pattern foo)) |
| 08:55 | clojurebot | #object[sandbox$eval47$fn__48 0x34af2848 "sandbox$eval47$fn__48@34af2848"] |
| 08:55 | sdegutis | ,(let[foo"bar"](re-pattern foo)) |
| 08:55 | clojurebot | #"bar" |
| 08:55 | sdegutis | yay |
| 09:24 | sdegutis | hey |
| 10:19 | sdegutis | Hello? |
| 10:19 | sdegutis | How do you use ring-mock along with sessions? |
| 10:19 | sdegutis | I'm having trouble |
| 10:34 | Glenjamin | sdegutis: peridot might help there |
| 10:34 | Glenjamin | it builds a concept of a session over ring-mock |
| 10:34 | Glenjamin | with a cookie jar |
| 10:34 | sdegutis | Glenjamin: I remember using it a few years ago, but it looks since abandoned, and I remember having issues with it |
| 10:35 | Glenjamin | i somehow inherited it. it doesn't change much now - only major issues i'm aware of are around multipart uploads |
| 10:35 | sdegutis | Git says I removed peridot on April 29, 2013. |
| 10:36 | Glenjamin | to get a session in ring-mock, you need to make a cookiejar object, parse set-cookie headers from responses and pass cookie headers into requests |
| 10:37 | sdegutis | Glenjamin: which seems also to be what https://github.com/rreas/ring-test does |
| 10:37 | sdegutis | Glenjamin: see also https://github.com/rreas/ring-test/blob/master/src/ring_test/core.clj |
| 10:38 | sdegutis | Glenjamin: looking at our git history, peridot was very similar to webrat/capybara in its api, for better or worse, whereas ring-test is a lot simpler |
| 10:40 | Glenjamin | yeah, peridot is intended to flow between requests, and mostly exists for kerodon |
| 10:47 | sdegutis | Glenjamin: never mind yeah i was remembering kerodon mostly |
| 10:56 | Glenjamin | slightly off-topic, but does anyone know if there's a simple Haskell testing framework that's as easy to use as the tests in here: https://github.com/glenjamin/defshef-blackjack/blob/master/clojure/src/defshef/blackjack.clj |
| 11:09 | jjmalina | anyone recommend some resources for getting around the limitation of tail call recursion? like what if you need two different recursive calls? |
| 11:10 | arrdem | jjmalina: if you really need unbounded mutual recursion trampoline is typically what you'll use. |
| 11:10 | jjmalina | arrdem what do you mean by "unbounded mutual recursion"? |
| 11:11 | arrdem | jjmalina: if you have two fns which you want to mutually recur as if they had been tco rewritten into a goto block, you've got to use trampoline. |
| 11:11 | jjmalina | trampoline could work i suppose, just adds more complexity |
| 11:11 | jjmalina | in this case i am calling the same function, just with different arguments |
| 11:12 | arrdem | If it's a tail call you can just use recur |
| 11:12 | arrdem | Sorry. A tail call of the same arity. |
| 11:12 | arrdem | If you have to cross arities, you have to do a fn invocation. |
| 11:13 | jjmalina | basically it's a tree traversal |
| 11:14 | jjmalina | one recursive call goes left the other goes right, but then both results have to be handled |
| 11:20 | arrdem | Until you know you have to do something more advanced I'd suggest simply let binding the results of simple recursive calls. |
| 11:21 | sdegutis | Hi? |
| 11:52 | sdegutis | oh right, yeah |
| 11:52 | sdegutis | hi |
| 13:20 | someone1 | hi |
| 13:24 | ben_vulpes | hello! |
| 13:25 | someone1 | is there a rails like web framework for clojure? also with clojurescript support. I want to use datomic |
| 13:26 | ben_vulpes | nope. |
| 13:26 | someone1 | I tried to use jruby mixed with clojure and clojurescript in the rails asset pipeline ... but it is not that good |
| 13:43 | Lewix | https://github.com/6ewis/recruitersPickupLines/blob/master/bestLines.md contribute for the laugh |
| 13:48 | tolstoy | Is there a way to specific a list as a p/schema type, rather than vector or map? |
| 13:53 | tolstoy | I have a DSL-ish thing: (foo bar [:some "data"]) and want to validate that foo == foo and bar is a symbol, but the whole thing is in a list. Hm. Maybe convert to vector before calling validate? |
| 13:55 | amalloy | i would be surprised if validate cared about the difference between vectors and lists |
| 13:56 | tolstoy | I think you're right. I'm getting some other error I don't understand regardless. |
| 13:57 | tolstoy | Like, you know, using defn where I should be using def. |
| 14:51 | backnforth | So Eclipses ide works with Clojure? Can I use it to get variables values at a breakpoint? |
| 14:54 | ane | I don't think it has debugging |
| 14:54 | ane | cursive or cider can do debugging |
| 14:59 | backnforth | it does with java |
| 15:12 | backnforth | can i retrieve variable values at a breakpoint with cider? |
| 15:15 | bendlas | dnolen: hi, we're here at the vienna om.next meetup. we are working with the todomvc demo and try to complete it |
| 15:16 | dnolen | @bendlas: ok might be a slightly tricky, also I haven't really looked at it in a very long time. |
| 15:16 | bendlas | dnolen: we were wondering, how we were supposed to trigger rerenders asynchronously in the reconciler |
| 15:17 | dnolen | bendlas: I don't really understand that question |
| 15:17 | bendlas | dnolen: there seems to be a mismatch with {:value {:keys [:foo]}} vs {:value [:foo]} |
| 15:17 | dnolen | what's there does demo basic async calls & render |
| 15:18 | bendlas | we're trying to implement creation and it's already working, but the ui doesn't rerender |
| 15:18 | dnolen | bendlas: I think this is a typical misunderstanding |
| 15:18 | dnolen | {:values {:keys ...}} |
| 15:18 | dnolen | doesn't have a real meaning - it's just for humans |
| 15:18 | dnolen | the only thing that triggers re-renderings are explicit re-reads |
| 15:18 | dnolen | [(change/it!) :foo :bar] |
| 15:19 | bendlas | right, we tried that, but doesn't work |
| 15:19 | dnolen | components that depend on :foo and :bar will render when you run this query expression |
| 15:19 | bendlas | b/c ui rerenders before server returns |
| 15:19 | dnolen | bendlas: well you need to be specific about whether that query is needed both locally and remotely |
| 15:20 | dnolen | that is you can make it run twice |
| 15:20 | dnolen | bendlas: a better place to ask this question is in the Om Slack channel, lots of people there who can help this bit |
| 15:21 | bendlas | ok, so to rerun it on the client after the server returns (that was my question about async rerender), we would call merge! ? |
| 15:22 | dnolen | bendlas: I dont' think so, all there's a bunch of simple defaults in place to avoid having to customize really basic stuff |
| 15:22 | dnolen | bendlas: sorry I can't say much more at the moment, busy with some other stuff |
| 15:22 | bendlas | ya, sorry, don't want to keep you |
| 15:23 | bendlas | om.nnext? ;-) |
| 15:38 | kwladyka | hmm agents run function 1 time, atoms can run many times during conflict. Why not just always use agents? |
| 15:44 | rhg135 | agents use a thread pool |
| 15:49 | kwladyka | agent make new thread, atom operate on same shared state in the thread where is called |
| 15:50 | kwladyka | ? |
| 15:50 | kwladyka | but still not sure why use atoms over agents when generally everybody want run functions 1 time |
| 15:51 | amalloy | there are lots of things you generally want |
| 15:51 | amalloy | eg, you generally want functions run at a particular time |
| 15:52 | amalloy | which is not a feature agents offer |
| 15:54 | kwladyka | amalloy so it is the choice between run functions many times but immediately and one but don't know when? |
| 15:55 | kwladyka | still i can't imagine when atom is over agent? If i have to run something immediately for example to third part software i can just run that without atom. What i want to use with atom with danger of running it many times? |
| 15:58 | kwladyka | Even idempotent function, why run they many times if can be run once? Running them many times don't have anything. |
| 16:05 | dysfun | because it results in higher throughput on average |
| 16:06 | kwladyka | dysfun ok that is the argument |
| 16:09 | kwladyka | thx |
| 17:26 | Lewis | stupid question |
| 17:26 | Lewis | ,`(1 2 3 4) |
| 17:26 | clojurebot | (1 2 3 4) |
| 17:27 | Lewis | ,'(1 2 3 4) |
| 17:27 | clojurebot | (1 2 3 4) |
| 17:27 | Lewis | (= `(1 2 3 4) '(1 2 3 4)) |
| 17:27 | Lewis | ,(= `(1 2 3 4) '(1 2 3 4)) |
| 17:27 | clojurebot | true |
| 17:27 | Lewis | ,(class `(1 2 3 4) ) |
| 17:27 | clojurebot | clojure.lang.Cons |
| 17:28 | Lewis | ,(class '(1 2 3 4) ) |
| 17:28 | clojurebot | clojure.lang.PersistentList |
| 17:28 | TimMc | Lewis: Correct. :-) |
| 17:28 | Lewis | whats the difference between cons and persistentList? |
| 17:29 | TimMc | ,(ancestors (class `(1 2 3 4))) |
| 17:29 | clojurebot | #{clojure.lang.IObj clojure.lang.IMeta clojure.lang.Sequential clojure.lang.ASeq java.lang.Iterable ...} |
| 17:29 | TimMc | hrmf |
| 17:29 | TimMc | ,(apply println (ancestors (class `(1 2 3 4)))) |
| 17:29 | clojurebot | clojure.lang.IObj clojure.lang.IMeta clojure.lang.Sequential clojure.lang.ASeq java.lang.Iterable clojure.lang.IHashEq clojure.lang.Obj java.io.Serializable java.util.Collection clojure.lang.Seqable java.util.List clojure.lang.ISeq clojure.lang.IPersistentCollection java.lang.Object\n |
| 17:30 | TimMc | ,(apply println (ancestors (class '(1 2 3 4)))) |
| 17:30 | clojurebot | clojure.lang.IObj clojure.lang.IMeta clojure.lang.Sequential clojure.lang.ASeq clojure.lang.Counted java.lang.Iterable clojure.lang.IHashEq clojure.lang.Obj java.io.Serializable java.util.Collection clojure.lang.Seqable clojure.lang.IReduceInit java.util.List clojure.lang.ISeq clojure.lang.IPersistentCollection clojure.lang.IPersistentList java.lang.Object clojure.lang.IReduce clojure.lang.IPersis... |
| 17:32 | TimMc | Lewis: Anyway, to answer your question... not a whole lot. :-) |
| 17:33 | TimMc | They're both sequential, serially accessed data structures. |
| 17:34 | TimMc | Cons is a seq, whereas PersistentList is a list, and the difference is kinda subtle to nonexistent. |
| 17:40 | Lewis | TimMc: in other words, you dont know the diff either? |
| 17:41 | TimMc | Lewis: I can tell a story about what I think the difference is, but I don't think there's an official explanation. |
| 18:02 | wombawomba | what's the best library for doing http requests in cljs these days? |
| 18:05 | arrdem | wombawomba: clj-http still works just fine |
| 18:05 | arrdem | wombawomba: if you need async the choice is less obvious |
| 18:05 | wombawomba | async would be nice |
| 18:06 | arrdem | http-kit is probably more your speed then. |
| 18:06 | wombawomba | hmm |
| 18:06 | wombawomba | notw I wrote cljs |
| 18:07 | bsima | wombawomba: I think cljs-http is the equivalent https://github.com/r0man/cljs-http |
| 18:10 | wombawomba | okay |
| 18:31 | backnforth | How do I do a hot reload of my Clojure code when using the repl? |
| 18:37 | Glenjamin | anyone know how to go from 0x1F0A0 to the character at that unicode code point? |
| 18:38 | TEttinger | backnforth: there's a :reload additional argument that can be passed to require |
| 18:38 | TEttinger | Glenjamin: that's going to be tricky since that's really two chars |
| 18:38 | TEttinger | ,(Character. 0x1F0A0) ; just curious, not sure if this works |
| 18:39 | clojurebot | #error {\n :cause "java.lang.Long cannot be cast to java.lang.Character"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to java.lang.Character"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" -1]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" -1]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.jav... |
| 18:40 | Glenjamin | oh good, the docs for Character have a brief discussion about how terrible a choice UTF-16 was |
| 18:41 | Glenjamin | with no hint of an alternative |
| 18:41 | justin_smith | backnforth: another options is load-file, especially useful when you want to load code from a local copy of a file (eg. if really you loaded from a jar, but want to redefine some of the code from a copy of the file from the jar) |
| 18:42 | Glenjamin | hrm, actually in my case the first byte doesn't need to change |
| 18:44 | justin_smith | backnforth: also, environments like CIDER or fireplace should have a keystroke to send the current function or file to the repl (and this will use load-file under the hood) |
| 18:46 | backnforth | justin_smith, interesting |
| 18:46 | backnforth | justin_smith, I haven't gotten around to installing vim-cider yet |
| 18:46 | backnforth | justin_smith, only vim-fireplace |
| 18:50 | Deraen | backnforth: Fireplace includes the functionality to reload namespaces (cpr) and evaluate forms (cpp, cp<motion>). |
| 18:52 | Glenjamin | ,(Character/toChars 0x1F0A0) |
| 18:52 | clojurebot | #object["[C" 0x9c32307 "[C@9c32307"] |
| 18:52 | Glenjamin | now how do I turn a primitive character array into a string? |
| 18:53 | Glenjamin | oh, duh |
| 18:53 | Glenjamin | ,(String. (Character/toChars 0x1F0A0)) |
| 18:53 | clojurebot | "🂠" |
| 18:53 | Glenjamin | ,(String. (Character/toChars (inc 0x1F0A0))) |
| 18:53 | clojurebot | "🂡" |
| 19:28 | backnforth | Is it ok to have a "let" function inside of a loop? I keep getting a NullPointerException because of it. I have done much debugging and the error is coming from the viable value I'm trying to assign with. |
| 19:29 | Glenjamin | backnforth: can you post some code? (via a pastebin of some sort) |
| 19:31 | backnforth | Glenjamin, certainly |
| 19:36 | backnforth | http://pastebin.com/GA0cf55H |
| 19:36 | backnforth | Glenjamin, The error happens at the first let on the second iteration of the loop |
| 19:37 | Glenjamin | you're trying to access some of those vectors as if they were maps |
| 19:40 | backnforth | Glenjamin, It accesses work outside of the let |
| 19:41 | backnforth | Glenjamin, And it should work because the vectors hold maps |
| 19:41 | Glenjamin | it's hard to follow what's going on, i'd suggest breaking it up into a series of smaller functions so you can check those bits independently |
| 19:42 | Glenjamin | but for example, you do (:paths tempVector) |
| 19:42 | Glenjamin | but tempVector is a vector, so that'l always be nil |
| 19:43 | backnforth | Glenjamin, Ah. How could I go about simply making it a map? |
| 19:44 | backnforth | Glenjamin, {} yes |
| 19:44 | Glenjamin | yes |
| 19:44 | Glenjamin | it's really hard to follow this function, i think mostly because it's operating at a bunch of different levels of abstraction |
| 19:45 | Glenjamin | here's more detail on what I mean by that: http://principles-wiki.net/principles:single_level_of_abstraction |
| 19:45 | amalloy | regularization of whitespace would help a lot too |
| 19:47 | backnforth | interesting, thank you |
| 19:48 | backnforth | Glenjamin, Weird. Now I'm getting an error at my first recur |
| 19:48 | backnforth | Saying I can only recur from tail possition |
| 19:49 | backnforth | I know recur can work with cond, but about if/else inside of a cond? |
| 19:58 | backnforth | Glenjamin, nvm, that was my fault for having a bad brace |
| 20:51 | bsima | Does anyone know much about core.match internals? |
| 20:51 | bsima | I could use some help improving this https://gist.github.com/bsima/f48eeb3d4531be1408287727016beb2a |
| 20:51 | bsima | see the tests on line 34. I'm pretty stumped about how to fix it |
| 21:36 | cespare | Is there a faster way to create an empty transient vector than (transient []) ? The cloning of the empty vector seems to be using a lot of cpu in a profile |
| 21:37 | justin_smith | cespare: transient shouldn't by cloning anything - all it needs to do is set a bit |
| 21:37 | justin_smith | unless I'm totally misremembering how transients work |
| 21:38 | dmac | justin_smith: I'm working on this with cespare; this is the expensive line that's showing up in our profile: https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/PersistentVector.java#L547 |
| 21:38 | dmac | justin_smith: specifically the .clone() |
| 21:39 | cespare | justin_smith: well, if you do (transient foo), then foo needs to remain undisturbed by whatever mutate-y stuff you do with the transient, yes? |
| 21:42 | justin_smith | transient calls asTransient https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L3209 which then calls transientvector's constructor https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/PersistentVector.java#L133 and all that does is flip some bits https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/PersistentVector.java#L523 |
| 21:42 | justin_smith | cespare: oh, wait, the editableRoot and editableTail methods do clone an array - not the whole vector, but one node |
| 21:43 | justin_smith | which dmac linked while I was source digging, heh |
| 22:51 | Lewis | justin_smith: how do you guys think in terms of recursion day in and day out |
| 22:52 | Lewis | https://gist.github.com/6ewis/4e280967cf6f33aed05463f3e4ec41ab this piece of code give me headaches |
| 22:52 | justin_smith | Lewis: you should almost always use cond instead of nested if |
| 22:52 | justin_smith | and you should use recur instead of that self call |
| 22:52 | Lewis | justin_smith: thats not my code |
| 22:53 | justin_smith | oh, I had no way of knowing that |
| 22:53 | Lewis | justin_smith: my solution is actually a one liner |
| 22:53 | Lewis | #(= (seq %) (reverse %)) |
| 22:54 | Lewis | justin_smith: i was looking at somebody else solution and I was flabbergasted by the fact that it made sense to him |
| 22:54 | Lewis | justin_smith: is it me or this code is overly complex and hard to follow |
| 22:54 | justin_smith | it's a direct translation of how you would write it in C |
| 22:54 | Lewis | i still dont get it but i get the idea |
| 22:55 | Lewis | really |
| 22:55 | justin_smith | complete with the annoying trailing braces |
| 22:56 | Lewis | justin_smith: ok ill have to study it |
| 22:57 | Lewis | ,(doc butlast) |
| 22:57 | clojurebot | "([coll]); Return a seq of all but the last item in coll, in linear time" |
| 22:57 | justin_smith | oh, I guess that part isn't like c, heh |
| 23:11 | amalloy | well, in C you'd simulate rest/butlast with start/end pointers |
| 23:13 | amalloy | incidentally that function is much simpler with no ifs at all: (defn palindrome? [xs] (or (not (next xs)) (and (= (first xs) (last xs)) (palindrome? (butlast (next xs)))))) |
| 23:22 | Lewis | amalloy: wow any suggestion on how to make the it easier on the mental load? |
| 23:23 | amalloy | practice, like anything |
| 23:23 | amalloy | do exercises if that helps |
| 23:27 | Lewis | amalloy: i meant the recursion stuff |
| 23:27 | amalloy | yep |
| 23:27 | amalloy | practice |
| 23:27 | Lewis | like your example and the gist i gave |
| 23:27 | amalloy | uh huh |
| 23:27 | amalloy | practice writing and reading recursive functions |
| 23:27 | amalloy | that's it |
| 23:27 | amalloy | no silver bullets |
| 23:32 | Lewis | amalloy: ok im on it |
| 23:48 | Lewis | amalloy: ahhh its pretty easy now |
| 23:48 | Lewis | im black belt in recursion :p |
| 23:53 | Lewis | amalloy: your solution is even more complicated |
| 23:53 | Lewis | sheesh |
| 23:53 | amalloy | it is literally less complicated: it replaces (if foo true bar) with (or foo bar) |
| 23:54 | amalloy | and likewise (if foo false bar) => (and foo bar) |
| 23:54 | Lewis | ,(doc and) |
| 23:54 | clojurebot | "([] [x] [x & next]); Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true." |
| 23:54 | Lewis | ,(and 1 2 3 4 5 false 3) |
| 23:54 | clojurebot | false |
| 23:55 | Lewis | ,(and 1 2 3 4 5 3) |
| 23:55 | clojurebot | 3 |
| 23:55 | Lewis | ,(doc or) |
| 23:55 | clojurebot | "([] [x] [x & next]); Evaluates exprs one at a time, from left to right. If a form returns a logical true value, or returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression. (or) returns nil." |
| 23:56 | Lewis | ,(or 1 2 3 4 5 true 4) |
| 23:56 | clojurebot | 1 |
| 23:56 | Lewis | ,(or false nil 3) |
| 23:56 | clojurebot | 3 |
| 23:57 | Lewis | amalloy: that's so misleading, i expect or to be || and and to be AND |
| 23:57 | Lewis | && |
| 23:58 | amalloy | okay, and...it is |
| 23:58 | amalloy | not sure how you are misleading yourself here |