2015-08-26
| 00:01 | amalloy | ,(/ Math/PI 4) |
| 00:01 | clojurebot | 0.7853981633974483 |
| 00:01 | amalloy | i think i actually meant pi/2 when i claimed cos(x)=x would be between pi/4 and 0, but i happened to get it right |
| 00:03 | neoncontrails | Clever, clever |
| 00:06 | neoncontrails | So this isn't quite right |
| 00:06 | neoncontrails | ,(defn fix-iter [f initial] (take-while (fn [x] (not (= x (apply f x)))) (iterate (fn [x] (apply f x)) initial))) |
| 00:06 | clojurebot | #'sandbox/fix-iter |
| 00:07 | neoncontrails | ,(fix-iter Math/cos 1) |
| 00:07 | clojurebot | #error {\n :cause "Unable to find static field: cos in class java.lang.Math"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to find static field: cos in class java.lang.Math, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to find static... |
| 00:07 | amalloy | neoncontrails: you just mean (f x), not (apply f x) |
| 00:07 | TEttinger | ,(reduce #(if (= %1 %2) (reduced %2) %2) (iterate #(Math/cos %) 1)) |
| 00:07 | clojurebot | 0.7390851332151607 |
| 00:07 | amalloy | TEttinger: we are letting neoncontrails write it |
| 00:07 | amalloy | it is not a difficult exercise for you to do |
| 00:07 | TEttinger | I didn't know if it would work |
| 00:07 | TEttinger | (also I was going to guess mine was going to take forever) |
| 00:08 | amalloy | and also Math/cos isn't a function, as you discovered, neoncontrails; you need to wrap it up in one via #(Math/cos %) |
| 00:09 | sdegutis | ,(map (comp first (juxt identity (comp prn inc))) [1 2 3]) |
| 00:09 | clojurebot | (2\n3\n4\n1 2 3) |
| 00:09 | sdegutis | bwahaha |
| 00:09 | neoncontrails | Oh, that makes sense. I was about to say, it didn't work before in the absence of (apply ...) either |
| 00:09 | sdegutis | it's like tap |
| 00:09 | TEttinger | that's a clever technique though, neoncontrails, to avoid passing pairs by actually generating the next element in the function that is passed to take-while that can't take 2 args |
| 00:12 | amalloy | TEttinger: there is a rather simpler way to avoid generating pairs, which is to just write the tail-recursive function yourself |
| 00:12 | amalloy | (defn fix [f x] (let [y (f x)] (if (= x y) x (recur f y)))) |
| 00:12 | amalloy | ,(defn fix [f x] (let [y (f x)] (if (= x y) x (recur f y)))) |
| 00:13 | TEttinger | we seem to have found remarkably similar methods |
| 00:13 | clojurebot | #'sandbox/fix |
| 00:13 | amalloy | ,(fix #(Math/cos %) 1) |
| 00:13 | clojurebot | 0.7390851332151607 |
| 00:13 | sdegutis | Why did I need to do `lein clean` before (-> (require 'my.namespace) (ns-publics)) saw the new vars during `lein run`? |
| 00:13 | sdegutis | Btw that's pseudocode, the point is the main thing. |
| 00:16 | neoncontrails | I'm getting flashbacks to Ch1 SICP... very useful to see the tail-recursive control flow mapped to Clojure |
| 00:18 | sdegutis | amalloy: do you know? |
| 00:29 | sdegutis | Is *ns* not guaranteed to be the last value of (ns)? |
| 00:29 | sdegutis | Ah right, only at compile-time is it meaningful. At runtime it's who knows, in this case user. |
| 00:32 | sdegutis | ... |
| 00:32 | sdegutis | Raise your hand if you have me on /ignore |
| 00:32 | TEttinger | hi sdegutis |
| 00:32 | sdegutis | :) |
| 00:32 | sdegutis | How re you TEttinger2 |
| 00:33 | TEttinger | I'm not sure why lein clean is sometimes necessary |
| 00:33 | sdegutis | Fwiw I solved the second problem with (def this-ns *ns*) |
| 00:33 | TEttinger | usually it's gen-class or java-related |
| 00:33 | sdegutis | Ahh could be that. Thanks. |
| 00:33 | sdegutis | amalloy: you didnt raise your hand |
| 00:34 | TEttinger | gen-class only happens when you compile, and while lein run probably could be cleaning beforehand, I don't know if all versions do. |
| 00:34 | sdegutis | Very good point. |
| 00:35 | TEttinger | (it might be compiling only things that don't already have compiled versions in the output) |
| 00:35 | sdegutis | makes sense |
| 00:35 | TEttinger | (which would save a lot of time, yeah) |
| 00:35 | TEttinger | if it did a full recompile every time you did lein run, and you had a lot of gen-class stuff that hadn't actually changed, it would be slow |
| 00:36 | sdegutis | true |
| 00:36 | TEttinger | but I don't know how lein works really. |
| 00:44 | sdegutis | Is it possible to recreate something like (:require [my.namespace :as foo]) outside of (ns)? |
| 00:44 | sdegutis | Ah, alias I think. |
| 00:46 | sdegutis | ,(do (alias 's 'clojure.str) s/join) |
| 00:47 | clojurebot | #error {\n :cause "No namespace: clojure.str found"\n :via\n [{:type java.lang.Exception\n :message "No namespace: clojure.str found"\n :at [clojure.core$the_ns invokeStatic "core.clj" 4011]}]\n :trace\n [[clojure.core$the_ns invokeStatic "core.clj" 4011]\n [clojure.core$alias invokeStatic "core.clj" 4113]\n [clojure.core$alias invoke "core.clj" -1]\n [sandbox$eval25 invokeStatic "NO_SOURCE... |
| 00:47 | sdegutis | ,(do (alias 's 'clojure.string) s/join) |
| 00:47 | clojurebot | #object[clojure.string$join 0x251f2a0a "clojure.string$join@251f2a0a"] |
| 00:47 | sdegutis | Phew. |
| 00:51 | darth10 | //whois darth10 |
| 00:51 | darth10 | oops |
| 00:54 | crocket | It seems clojure is a very practical community. |
| 01:20 | cljnewbie | haven't got any response in #clojure-beginners, so maybe you can answer my supposedly easy question: https://www.refheap.com/921878412593a9371d1560eb5 :) |
| 01:22 | rweir | "Duplicate teste" <- really? |
| 01:22 | luxbock | ,(doc case) |
| 01:22 | clojurebot | "([e & clauses]); Takes an expression, and a set of clauses. Each clause can take the form of either: test-constant result-expr (test-constant1 ... test-constantN) result-expr The test-constants are not evaluated. They must be compile-time literals, and need not be quoted. If the expression is equal to a test-constant, the corresponding result-expr is returned. A single default expression can foll... |
| 01:23 | luxbock | I think the issue is that the (key-code :kw) is not interpreted as an expression inside case |
| 01:23 | amalloy | cljnewbie: case expressions must be constant |
| 01:23 | amalloy | "The test-constants are not evaluated." |
| 01:23 | cljnewbie | amalloy: ah :) thank you very much |
| 01:24 | amalloy | so in fact (key-code :dpad-up) will match either the symbol key-code or the keyword :dpad-up |
| 01:24 | cljnewbie | cljnewbie: so the cond is the straight-forward way to write this or do you see a more elegant way to write this? |
| 01:25 | cljnewbie | alloyed: see above :) |
| 01:25 | luxbock | cljnewbie: check out condp |
| 01:25 | cljnewbie | amalloy: see above... sorry channel, my coffee-level is too low currently |
| 01:25 | cljnewbie | luxbock: thanks |
| 01:25 | cljnewbie | alloyed: sorry for the misplaced ping |
| 01:26 | amalloy | right, (condp = (:key screen) ...) is the easiest way |
| 01:33 | cljnewbie | works, excellent. thanks everyone |
| 01:37 | jeaye | cljnewbie: Also, note that your println has a typo, the last one. |
| 01:38 | cljnewbie | jeaye: thanks, if written the cond-version afresh though |
| 01:39 | cljnewbie | condp* |
| 02:39 | en590 | hi everyone |
| 04:21 | Rurik_ | #j #clojure-beginners |
| 04:21 | Rurik_ | err |
| 04:21 | Rurik_ | sorry |
| 04:25 | Rurik_ | can anyone explain why a list is quoted? |
| 04:26 | TEttinger | Rurik_: do you mean like '(1 2 3) ? |
| 04:26 | Rurik_ | yep |
| 04:26 | TEttinger | that's because if you don't quote a list, it's treated as a function call |
| 04:26 | TEttinger | ,(+ 1 2 3) |
| 04:26 | clojurebot | 6 |
| 04:26 | Rurik_ | ah |
| 04:27 | Rurik_ | silly me |
| 04:27 | Rurik_ | I forgot the first thing bout lisp |
| 04:28 | TEttinger | vectors are the most common way of putting data in a program in a list-like form, in clojure. I can't remember the last time I used '(1 2 3) instead of [1 2 3] |
| 04:28 | TEttinger | there are cases for it |
| 04:29 | Rurik_ | TEttinger: I am doing the clojurescript koans |
| 04:29 | TEttinger | ,(conj '(1 2 3) 4) |
| 04:29 | clojurebot | (4 1 2 3) |
| 04:29 | TEttinger | ,(conj [1 2 3] 4) |
| 04:29 | clojurebot | [1 2 3 4] |
| 04:30 | expez | Is Luke VanderHart, aka levand, of quiescent fame ever around these parts? |
| 04:45 | Rurik_ | What would be the answer to this koan? Higher-order functions take function arguments |
| 04:45 | Rurik_ | (= 25 ( (fn [n] (* n n)))) |
| 04:46 | Rurik_ | nvm, solved |
| 05:02 | Rurik_ | '(filter (fn [x] false) '(:anything :goes :here)) |
| 05:02 | Rurik_ | uh |
| 05:02 | Rurik_ | ,(filter (fn [x] false) '(:anything :goes :here)) |
| 05:02 | clojurebot | () |
| 06:03 | negaduck | hi! Are transducers a replacement for reducers? I'm a bit confused. Please give me a hint when reducers better suit the job. Is it about r/fold, which can do parallel execution? |
| 06:05 | dstockton | negaduck: http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming |
| 06:06 | dstockton | they are not a replacement but a further abstraction |
| 06:10 | clgv | hyPiRion: ping |
| 06:12 | hyPiRion | clgv: pong |
| 06:13 | negaduck | dstockton: do I get it right that if I need either of them, I just use transducers |
| 06:14 | clgv | hyPiRion: about the leiningen self-signed certificate issue - did Leiningen 2.5.0 check the certificates at all? |
| 06:14 | hyPiRion | clgv: yes |
| 06:14 | clgv | hyPiRion: I commented the :certificates option and 2.5.0 still works |
| 06:14 | negaduck | could you give me a hint, when should I use reducers instead of transducers? |
| 06:15 | clgv | negaduck: when you need built-in parallelization |
| 06:15 | hyPiRion | clgv: what do you mean by works? It lets you upload/deploy stuff without checking the cert? |
| 06:16 | clgv | hyPiRion: it lets me download/check artifacts without checking the certificate as it seems |
| 06:16 | clgv | hyPiRion: so the expected pem-file just contains the certificate I want to trust, right? |
| 06:16 | hyPiRion | clgv: right |
| 06:17 | clgv | hyPiRion: then it seems to me that 2.5.0 just does not check the certificate and from 2.5.1 the check is done but the specification of my pem file is ignored |
| 06:18 | hyPiRion | clgv: 2.5.1 should die if you specify certificates, so I guess the profile is shadowed |
| 06:19 | clgv | hyPiRion: my pem file contains the first part wrapped in BEGIN CERTIFICATE and END CERTIFICATE that you get when querying openssl s_client -showcerts -connect myrepository.tld:443 </dev/null |
| 06:19 | hyPiRion | clgv: yep, that's what it's supposed to be |
| 06:19 | clgv | hyPiRion: and 2.5.2 should work with the :certificates setting |
| 06:19 | hyPiRion | right |
| 06:20 | clgv | hyPiRion: :certificates is a toplevel option in project.clj as shown in the sample-project.clj right? |
| 06:20 | hyPiRion | clgv: right |
| 06:20 | hyPiRion | I'll be back in 30-40 mins |
| 06:21 | clgv | ok. I'll update the issue meanwhile |
| 06:27 | tdammers | I have a project here where lein install works fine, but lein tests throws compiler errors in the project's core module |
| 06:27 | tdammers | a :require from core.clj fails |
| 06:28 | tdammers | any ideas how that is possible? |
| 06:33 | clgv | tdammers: some error in your testcode |
| 06:34 | tdammers | clgv: really? an error in my test code can cause a :require in the tested code to fail? |
| 06:34 | tdammers | actually, the :require also fails when doing it from the repl |
| 06:34 | clgv | tdammers: or some dependency problems with :dev :dependencies |
| 06:35 | tdammers | I don't have any :dev dependencies |
| 06:35 | clgv | tdammers: you description is too vague to do more than guessing .. |
| 06:35 | tdammers | yeah, I was afraid it would be |
| 06:35 | clgv | make a minimal example that still fails and load that up |
| 06:36 | tdammers | that's gonna be tricky, but I'll try |
| 06:36 | clgv | tdammers: maybe you already find the problem like that |
| 06:37 | tdammers | I'm familiar with the routine |
| 06:37 | clgv | tdammers: investigate the stacktrace/causetrace of the exception more closely |
| 06:37 | tdammers | it says that it can't find the thing I'm trying to :require on the classpath |
| 06:40 | tdammers | great, my minimal example doesn't fail |
| 06:41 | tdammers | oooooooooh... |
| 06:41 | tdammers | [org.clojure/clojure "1.6.0"] |
| 06:42 | tdammers | that one fails |
| 06:42 | tdammers | but if I change it to 1.7.0, it works |
| 06:47 | clgv | tdammers: that's weird. so maybe you are using a 1.7.0 feature? new function or similar? that might prevent the namespace from being compiled (exception) and hence it is "not found" |
| 06:49 | tdammers | yeah, that library I'm using uses cljc |
| 07:21 | kungi | how can I check if a vector of instants is in time increasing order? |
| 07:21 | clgv | hyPiRion: I confirmed that the file in :certificates is actually read by using a damaged certificate file which resulted in a different exception within sun.security.x509.X509CertImpl |
| 07:21 | kungi | I cannot use > or < because they compare numbers .... |
| 07:22 | clgv | kungi: you can reduce over the vector and short circuit on order violation via `(reduced false)` |
| 07:23 | clgv | always return the new instant from the reducing function |
| 07:23 | clgv | kungi: or did you mean how to compare two instants? |
| 07:24 | kungi | clgv: no I meant something like (is (apply > [vector-of-instants])) |
| 07:25 | clgv | kungi: (reduce (fn [a, b] (if (instant-larger? a b) b (reduced false))) vector-of-instants) |
| 07:26 | clgv | kungi: you'll end up either with `false` or the smallest instant |
| 07:26 | clgv | which is truthy |
| 07:26 | kungi | what is "(reduced false)" ? |
| 07:26 | TEttinger | it's cool. |
| 07:26 | clgv | ,(doc reduced) |
| 07:26 | clojurebot | "([x]); Wraps x in a way such that a reduce will terminate with the value x" |
| 07:26 | kungi | Oh! |
| 07:27 | TEttinger | it shortcuts the reduce call to end early |
| 07:27 | TEttinger | amazing stuff |
| 07:27 | TEttinger | here it will just return false |
| 07:27 | kungi | This is much nicer than my solution :-) I converted all the instants to longs and used ">" |
| 07:27 | TEttinger | but you can have it return other stuff too |
| 07:28 | clgv | ,(reduce (fn [s, x] (if (< x 4) (+ s x) (reduced s))) (range 10)) |
| 07:28 | clojurebot | 6 |
| 07:28 | lumafi | (every? (partial apply before?) (partition 2 1 vector-of-instants)) |
| 07:28 | lumafi | this should also work |
| 07:28 | lumafi | or #(before? %1 %2) instead of the partial |
| 07:28 | clgv | lumafi: but it's pretty complex in comparison |
| 07:29 | clgv | and lazy |
| 07:29 | clgv | the `partition` part I mean |
| 07:30 | kungi | lumafi: hmm this does not test monotonically increasing if I see correctly. because it only comepares value 1 and 2, 3 and 4 ... |
| 07:30 | lumafi | kungi, it compares 1 and 2, 2 and 3, 3 and 4 etc. |
| 07:30 | kungi | lumafi: oh sorry i did not see the 1 in the partition |
| 07:30 | en590 | hi every1 |
| 07:30 | lumafi | ,(partition 2 1 (range 5)) |
| 07:30 | clojurebot | ((0 1) (1 2) (2 3) (3 4)) |
| 07:32 | en590 | do any of you all have clojure jobs? |
| 07:34 | kungi | en590: I made my own :-) |
| 07:34 | clgv | en590: if you count university jobs, then yes ;) |
| 07:38 | en590 | that's cooler than what i want to do just work for some company that uses clojure |
| 07:39 | en590 | but i gotta learn a lot more first can't keep being distracted by irc |
| 07:42 | phillord | Just on the off-chance, has anyone written a library for easy invocation of Maven from Clojure? |
| 08:02 | schmir | phillord: look at what leiningen itself is using |
| 08:05 | clgv | phillord: there are libs for calling external programs, if that is what you mean by "invocation of maven" |
| 08:07 | phillord | clgv: Yeah, I could do that, I think I may have to |
| 08:08 | phillord | What I have done is used maven to launch an nrepl and I was toying with the possibility having maven run goals within the same JVM |
| 08:08 | phillord | I suspect that it's going to be more effort than it is worth |
| 08:17 | clgv | phillord: ah I see, you'd have to check whether maven has an API for that |
| 08:48 | Olajyd | What is the difference between the `pmap` and `map`, I don’t really undersatnd the documentation :| |
| 08:49 | gilliard | ,(doc pmap) |
| 08:49 | clojurebot | "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead." |
| 08:49 | TEttinger | Olajyd: pmap should have the same result as map, but sometimes does it faster (and often slower) |
| 08:49 | gilliard | "f is applied in parallel" - ie using multiple threads. |
| 08:49 | TEttinger | usually you're better off with map |
| 08:50 | Olajyd | TEttinger, Hi.. :) |
| 08:50 | TEttinger | hello! |
| 08:50 | Olajyd | gilliard too, hello :) |
| 08:50 | gilliard | Hi :) |
| 08:51 | gilliard | map is like asking a kid to get your shopping. pmap is like asking ten kids to get 1/10 of the shopping each. |
| 08:51 | TEttinger | if you have a function that uses a lot of CPU and can be run in parallel, pmap can use multiple threads to allow a multicore processor to be fully used (disk reading stuff would probably not benefit from this, but looping over many millions of complex pieces of data in each run of the function would) |
| 08:52 | TEttinger | gilliard: yeah, and they all wait in the same line at the store |
| 08:52 | TEttinger | there's some overhead for each one |
| 08:53 | Olajyd | great |
| 08:53 | Olajyd | so say (defn foo [x] (let [aa @a] (swap! a (fn [&args] x)) aa)), and (def a (atom 0)) (map foo (range 1 20)) |
| 08:53 | Olajyd | and using (def a (atom 0)) (pmap foo (range 1 20)) |
| 08:54 | Olajyd | will produce different results I guess? |
| 08:55 | TEttinger | I would assume so. (swap! a (fn [&args] x)) can also be written as (reset! a x) |
| 08:57 | TEttinger | clojure has some tools to help with this though. one good one is that swap! with the right functions can be used just fine with pmap |
| 08:57 | TEttinger | ,(def a (atom 0)) |
| 08:57 | clojurebot | #'sandbox/a |
| 08:57 | TEttinger | ,(defn foo [x] (let [aa @a] (swap! a inc))) |
| 08:57 | clojurebot | #'sandbox/foo |
| 08:57 | TEttinger | I can't pmap in a sandbox |
| 08:58 | TEttinger | ,(map foo (range 1 20)) |
| 08:58 | clojurebot | (1 2 3 4 5 ...) |
| 08:58 | Olajyd | TEttinger, I was advised to not get used to using atoms to mutate data structures, and sometimes I’m tempted to do so, because I probably need to update a particular data structure to perform other functions. |
| 08:58 | TEttinger | order doesn't matter for inc, or any addition by a constant |
| 08:58 | TEttinger | yeah, there are some good ways to handle mutation in a contained area if you need it |
| 08:59 | TEttinger | loop and recur are used together to do all sorts of code that can replace mutation. |
| 09:00 | TEttinger | transients are mutable snapshots of a clojure data structure, that must become immutable again by the time the function ends |
| 09:00 | Olajyd | hmmm |
| 09:01 | TEttinger | transients don't support the whole seq-based set of fns in the standard lib |
| 09:01 | TEttinger | loop and recur are a bit tricky at first but really do a lot of things |
| 09:01 | TEttinger | if you need to perform other functions, that sounds like a loop situation |
| 09:04 | TEttinger | the really good thing about loop is that you control when, and how, you go into the next iteration by using recur, even if you have multiple bindings that are being updated in each iteration. |
| 09:05 | TEttinger | with map, an iteration is just a function called on one element of each collection you pass it. with for, it's a combination of every grouping of collections. but with loop, you could recur in more elaborate ways |
| 09:07 | Olajyd | ok, say I want to do a loop into a map, is this possible |
| 09:08 | Olajyd | Plus can we keep track of state in a map? |
| 09:09 | TEttinger | sort of. state-tracking is easier with loop, and possible though not always easy with reduce (which can produce a collection too!) |
| 09:09 | TEttinger | do you have an example? |
| 09:09 | TEttinger | of what you use an atom for now? |
| 09:13 | Olajyd | Its in relation to the problem you help me solve the other day |
| 09:19 | sdegutis | Hello. |
| 09:20 | TEttinger | &(loop [coll [1] state 1] (if (> (count coll) 10) coll (recur (conj coll state) (+ (last coll) state)))) |
| 09:20 | lazybot | ⇒ [1 1 2 3 5 8 13 21 34 55 89] |
| 09:20 | Olajyd | TEttinger, so my PM says the rows in of type `JavaRDD` which is similar to clojure lazy-sequence, There’s no inherent way of changing the type from clojure lazy sequence to type JavaRDD, and like you suggested, I could use an atom to keep track of state, or use reductions (which will work a given sequence or clojure lazy sequence) but will not work for the particular data type, he wants me to apply that function to. So I used an atom to hack my way throu |
| 09:20 | Olajyd | :), now we dont want to use an atom but come up with another way of fixing the problem |
| 09:20 | sdegutis | If you do (require 'foo) instead of (ns (:require [foo])), how can you then do (foo/bar) somewhere inside that namespace without the compiler claiming that namespace 'foo doesn't exist? |
| 09:21 | TEttinger | gotcha |
| 09:21 | TEttinger | Olajyd: it's likely the JavaRDD is mutable, and you can use mutable java objects just fine from clojure |
| 09:22 | Olajyd | TEttinger, anyone in particular? |
| 09:22 | TEttinger | how is it like lazy sequences? |
| 09:22 | TEttinger | uh, let's see |
| 09:23 | justin_smith | sdegutis: you can't, you'll have to use resolve |
| 09:23 | sdegutis | I was afraid of that. |
| 09:23 | sdegutis | You mean ns-resolve right? |
| 09:23 | TEttinger | ,(let [muta (java.util.HashMap.)] (.put muta "a" 1) (.put muta "b" 2) (.put muta "c" 3) muta) |
| 09:23 | Olajyd | TEttinger, meaning its lazily evaluated too |
| 09:24 | clojurebot | {"b" 2, "c" 3, "a" 1} |
| 09:24 | justin_smith | sdegutis: eh, resolve, ns-resolve they are just two syntaxes for the same shit |
| 09:24 | Olajyd | TEttinger, you still remmeber the problem right? |
| 09:24 | TEttinger | vaguely |
| 09:25 | TEttinger | I remember I used reductions but I don't remember the JavaRDD part |
| 09:25 | sdegutis | justin_smith: resolve takes an implicit *ns* which in this case won't let me specify the foo/ part |
| 09:26 | justin_smith | ,(resolve 'clojure.string/join) |
| 09:26 | clojurebot | #'clojure.string/join |
| 09:26 | sdegutis | Ooooh. |
| 09:26 | sdegutis | Cool. |
| 09:26 | TEttinger | is it this class, Olajyd? https://spark.apache.org/docs/latest/api/java/org/apache/spark/api/java/JavaRDD.html |
| 09:26 | sdegutis | I was doing ##(ns-resolve 'clojure.string 'join) |
| 09:26 | lazybot | java.lang.SecurityException: You tripped the alarm! ns-resolve is bad! |
| 09:26 | Olajyd | TEttinger, a function to fill in an empty column from the last non-empty value |
| 09:26 | sdegutis | ,(ns-resolve 'clojure.string 'join) |
| 09:26 | clojurebot | #'clojure.string/join |
| 09:26 | TEttinger | right! |
| 09:26 | Olajyd | TEttinger, sure it is ::) |
| 09:27 | sdegutis | Can you make your own deref-able by implementing some protocol (via proxy)? |
| 09:27 | justin_smith | ,clojure.lang.IDeref |
| 09:27 | clojurebot | clojure.lang.IDeref |
| 09:28 | sdegutis | Ah yep clojure.lang.IDeref just found it in core.clj |
| 09:30 | sdegutis | ,@(proxy [clojure.lang.IDeref] [] (deref [] 23)) |
| 09:30 | clojurebot | 23 |
| 09:30 | sdegutis | yay |
| 09:30 | sdegutis | Is there another way of creating a defer-able in Clojure? |
| 09:31 | justin_smith | promises and delays implement IDeref |
| 09:32 | sdegutis | I meant a custom one. |
| 09:35 | TEttinger | Olajyd: hm, I'm not sure how to work this RDD solution. http://stackoverflow.com/a/26060065 |
| 09:35 | TEttinger | it |
| 09:36 | TEttinger | it's mentioned that RDDs are shuffled when they're used, there likely isn't a reliable ordering? |
| 09:40 | sdegutis | I've started considering that maybe loading namespaces should be a service that can be started/stopped via stuart sierra's Component thing. |
| 09:41 | clgv | sdegutis: there is reify as well |
| 09:42 | sdegutis | wait a second!! |
| 09:43 | sdegutis | Isn't there a way to set an individual namespace to be compiled ahead of time? |
| 09:43 | clgv | adereth: :aot in project.clj |
| 09:43 | clgv | sdegutis: ^^ |
| 09:44 | sdegutis | ahh |
| 09:44 | sdegutis | Thanks, I'll read up on what the effects of that are. |
| 09:57 | TEttinger | $mail Olajyd consider using a Clojure binding to Spark, this one seems to be able to go back and forth from seq to RDD https://github.com/yieldbot/flambo#resilient-distributed-datasets-rdds |
| 09:57 | lazybot | Message saved. |
| 09:58 | blacbird | Anyone here have an idea why I can connect to a database using clojure.java.jdbc but not Korma? If it matters, it is an app running on elastic beanstalk worker tier (tomcat). The error messages are unhelpful to say the least, but from what I gather korma is having problems establishing a connection. It looks like it also uses jdbc under the hood, but maybe the pooling library is causing problems? |
| 09:59 | sdegutis | Sorry I use Datomic. |
| 10:00 | TEttinger | hey Olajyd, $mail |
| 10:00 | ddellacosta | blacbird: it's very easy to use c.j.j without Korma (arguably easier) |
| 10:01 | ddellacosta | blacbird: what exactly are you trying to do? Just try a simple select or something if you are simply trying to diagnose the connection, I suppose |
| 10:01 | blacbird | ddellacosta: if i had to do it again, i'd use that or honeysql. yup, just a simple select trying to figure out what is going wrong |
| 10:02 | ddellacosta | blacbird: honeysql + c.j.j is a much better choice in my opinion. :-) |
| 10:02 | blacbird | ddellacosta: really my questions is how in the world do i debug this. "it works fine witha local database" but we are moving it to aws and all of a sudden korma won't work |
| 10:02 | ddellacosta | blacbird: can you try https://clojure.github.io/java.jdbc/#clojure.java.jdbc/get-connection for example? |
| 10:02 | ddellacosta | blacbird: seems like a decent place to start |
| 10:03 | blacbird | ddellacosta: ya a select with c.j.j works fine. i have a test function that first does it with c.j.j then korma using the same env variables, cjj works fine |
| 10:04 | ddellacosta | blacbird: er, hrm, can you put the korma exception in a gist or something and paste the link in? |
| 10:05 | ddellacosta | blacbird: for what it's worth we were using korma and the problems with pooling were actually what made us drop it. :-/ |
| 10:07 | ddellacosta | (context: https://github.com/korma/Korma/issues/64) |
| 10:07 | blacbird | ddellacosta: https://gist.github.com/anonymous/41983d26742740b7fe16 |
| 10:08 | blacbird | ddellacosta: ya i don't think i would choose it again |
| 10:08 | ddellacosta | yikes I may not be much help to you on thi sone |
| 10:09 | ddellacosta | *this one |
| 10:09 | blacbird | ddellacosta: haha no problem |
| 10:09 | ddellacosta | blacbird: but, so, plain old c.j.j connects just fine huh? |
| 10:10 | blacbird | ddellacosta: yup |
| 10:10 | ddellacosta | wonder if there's a way to toggle the connection pool off to test |
| 10:10 | ddellacosta | (in Korma I mean) |
| 10:11 | blacbird | ddellacosta: ya i thought i could pass {: maximum-pool-size 1, etc} to defdb but doesn't seem to be having an effect/changing anything |
| 10:12 | ddellacosta | blacbird: I think that's because korma creates a connection pool by default, regardless of the size |
| 10:12 | ddellacosta | blacbird: oh, looks like there's a :make-pool? setting? |
| 10:12 | ddellacosta | https://github.com/korma/Korma/blob/996f056ec73d27d80d76a4acffcac2970d23cebe/src/korma/db.clj#L135-L148 |
| 10:14 | blacbird | ddellacosta: i'll try setting it to false |
| 10:15 | ddellacosta | blacbird: anyways, yeah, at this point I'd just be digging into the korma source to try to debug...not sure I can offer much more, sorry. :-/ |
| 10:15 | ddellacosta | blacbird: but I wish you good luck! And suggest you move to honeysql ASAP. :-) |
| 10:15 | blacbird | ddellacosta: ok, thanks a lot for the help anyway, and I might just do that! |
| 10:15 | ddellacosta | blacbird: any time! |
| 10:17 | negaduck | hi! Is it ok to create them on events in cljs? Are they disposable? |
| 10:18 | negaduck | what if I use them instead of promises to read from them only once? |
| 10:18 | ddellacosta | negaduck: what is "them?" |
| 10:19 | negaduck | ddellacosta: I'm sorry, core.async/chan |
| 10:20 | ddellacosta | negaduck: ah...I would caution against creating go blocks inside event handlers |
| 10:20 | ddellacosta | negaduck: but of course it really depends on what you're doing and how--I'd have to see a specific example or try to understand your use-case |
| 10:20 | ddellacosta | negaduck: simply creating channels is not a big deal I suppose, but again depends on what you're doing= |
| 10:20 | ddellacosta | doing* |
| 10:21 | negaduck | ddellacosta: something like this: http://dimagog.github.io/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async/ |
| 10:22 | negaduck | creating a go block in ajax handler |
| 10:24 | ddellacosta | negaduck: that seems fine to me because it's not looping, it just goes away |
| 10:24 | ddellacosta | negaduck: although I struggle to see why one would do it this way, but I suppose it's just a toy example |
| 10:24 | ddellacosta | I'd be inclined simply to log right inside the callback...haha |
| 10:25 | ddellacosta | but anyways, yeah, seems fine to me, albeit pointless here |
| 10:27 | negaduck | ddellacosta: I'm going to make sequential gets like (<! (-> (ajax.get "http://whatever) (then "rel-something) (etc) ...)) |
| 10:27 | ddellacosta | and as one of the commenters mentions I would simply use put! in the callback vs. creating a go block and using >! |
| 10:28 | negaduck | ddellacosta: basically following rest rels |
| 10:28 | ddellacosta | negaduck: I'm not really seeing it from the kinda-pseudo-code you just pasted, I'd need to see a more full example. I'm not sure what you mean by "sequential gets." |
| 10:31 | negaduck | ddellacosta: get a rest entrypoint, get links from there and follow them like in slides 13 and 14 here: https://speakerdeck.com/basti1302/consuming-hypermedia-apis-with-traverson?slide=13 |
| 10:32 | negaduck | ddellacosta: this is built using promises, I want to write the same thing with core.async |
| 10:34 | ddellacosta | negaduck: I see. In that case I'd create a single channel that you are listening on in a go block elsewhere, pass that to the callback of whatever AJAX fn is GETing the values from the API |
| 10:34 | negaduck | ddellacosta: so the question is: is it ok to use chans to be written and read exactly once to be then thrown away |
| 10:34 | ddellacosta | negaduck: I mean, I suppose you could do that too to get something more imperative |
| 10:35 | ddellacosta | negaduck: exactly as in the article you linked to |
| 10:35 | ddellacosta | negaduck: but my inclination would be to accumulate results in a go block with a single channel |
| 10:36 | negaduck | ddellacosta: with a transducer maybe? |
| 10:36 | ddellacosta | negaduck: dunno, there are different ways to do it that are potentially equally valid depending on your app architecture |
| 10:36 | ddellacosta | negaduck: I don't know, depends on what you need the transducer for...haha |
| 10:37 | ddellacosta | negaduck: that is, I don't see where it fits in here particularly |
| 10:37 | negaduck | yes, just a thought |
| 10:40 | negaduck | ddellacosta: ok, I'll think about a single channel |
| 10:40 | negaduck | ddellacosta: thanks |
| 10:40 | ddellacosta | negaduck: I mean, that's how I'd do it but I think something like a let block inside a go block emulating the style in the article you linked to above is reasonable too |
| 10:41 | ddellacosta | negaduck: but in any case, good luck! |
| 11:00 | negaduck | ddellacosta: is it necessary to close a channel? Is it ok to throw away an unclosed one? |
| 11:01 | ddellacosta | negaduck: my understanding is that you want to close channels if you have set up go blocks listening to them on a loop |
| 11:02 | negaduck | ddellacosta: got it |
| 11:03 | ddellacosta | negaduck: (that is, assuming you no longer need them) |
| 11:04 | negaduck | ddellacosta: ok. Is put! like (go (<! ...))? Can't figure out the difference |
| 11:05 | justin_smith | negaduck: surely you mean (go (>! ...)) |
| 11:05 | ddellacosta | put! doesn't block |
| 11:05 | justin_smith | ddellacosta: (go ...) doesn't either |
| 11:06 | ddellacosta | justin_smith: sorry, I should clarify-- |
| 11:07 | ddellacosta | negaduck: >! needs to be called inside a go block. |
| 11:07 | justin_smith | iirc put! does not return a channel, but does take an optional callback |
| 11:07 | justin_smith | ddellacosta: what he asked was why you would use put! instead of making a go block and using >!, that is how I read it at least |
| 11:07 | negaduck | justin_smith: ddellacosta: is go block for sequential >! and <!, and put! is like a go block with a single operation? |
| 11:07 | ddellacosta | justin_smith: ah, missed that I guess |
| 11:07 | justin_smith | negaduck: not really |
| 11:08 | justin_smith | negaduck: unlike a go block, put! does not return a channel |
| 11:08 | justin_smith | negaduck: instead you can provide a callback that will be called when the value is consumed |
| 11:09 | justin_smith | or you can "fire and forget" of course |
| 11:10 | justin_smith | negaduck: it's true that go blocks are more flexible and can be used for a series of reads and writes of channels |
| 11:10 | negaduck | justin_smith: leaving the return value, are those two same? |
| 11:10 | justin_smith | if you ignore return values and don't use a callback they will behave the same, yes. But put! is more concise than making a go block of course syntax wise |
| 11:10 | sdegutis | ,(->> (range) (run! prn)) |
| 11:10 | ddellacosta | negaduck: think of put! kind of like a shorthand for the common use case of putting something in a channel without necessarily caring about what happens past that (other than the option for passing in a callback) |
| 11:10 | clojurebot | #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space> |
| 11:11 | sdegutis | ,(->> (range 100) (run! prn)) |
| 11:11 | clojurebot | 0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81\n82\n83\n84\n85\n86\n87\n88\n89\n90\n91\n92\n93\n94\n95\n96\n97\n98\n99\n |
| 11:11 | sdegutis | neat |
| 11:11 | ddellacosta | negaduck: without needing to set up a go block, especially if you don't need to return a channel from that |
| 11:11 | negaduck | I mean they do same thing, right? |
| 11:11 | justin_smith | right, except for the differences already described |
| 11:12 | negaduck | ddellacosta: justin_smith: many thanks |
| 11:38 | sdegutis | What is run! meant for? |
| 11:39 | sdegutis | I suppose something like this would make sense: (run! handle-request (incoming-requests)) |
| 11:39 | pjstadig | ,(doc run!) |
| 11:40 | clojurebot | "([proc coll]); Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the collection. Returns nil" |
| 11:40 | sdegutis | Where (incoming-requests) is just a seq or "process" that generates requests as they come in and just waits in between. |
| 11:40 | pjstadig | basically sounds like (dorun (map ...)) |
| 11:40 | sdegutis | Or (doseq [x coll] (f x)) |
| 11:41 | sdegutis | That's how I've always done it, dunno how run! is better. |
| 11:41 | pjstadig | it's not necessarily better, it is like (dorun (map ...)) |
| 11:41 | pjstadig | which you may want to use if you have some function to apply |
| 11:41 | pjstadig | as opposed to writing a body of a doseq |
| 11:45 | justin_smith | pjstadig: it is better because unlike map it does not create a lazy seq you won't be using |
| 11:47 | pjstadig | justin_smith: my understanding is that sdegutis was asking why run! is "better" than doseq |
| 11:47 | sdegutis | ,(let [proc prn, coll [1 2 3]] (do (reduce #(proc %2) nil coll) nil)) |
| 11:47 | clojurebot | 1\n2\n3\n |
| 11:47 | justin_smith | pjstadig: not making things you don't use is better |
| 11:47 | justin_smith | oh, doseq |
| 11:47 | sdegutis | justin_smith: I was wondering why there's run! when it's basically the same as doseq. |
| 11:47 | justin_smith | never mind |
| 11:47 | Bronsa | doseq still consumes a seq |
| 11:47 | justin_smith | syntax |
| 11:47 | justin_smith | Bronsa: wouldn't run! also consume one? |
| 11:47 | Bronsa | not necessarily |
| 11:48 | justin_smith | ahh... |
| 11:48 | Bronsa | it uses reduce internally |
| 11:48 | Bronsa | so it can exploit the new reducible colls |
| 11:48 | pjstadig | run! being a function also means that you can partial it, pass it as a value, return it as a value, etc. |
| 11:48 | pjstadig | it's just a different tool to be used in appropriate circumstances |
| 11:49 | sdegutis | run! is literally (do (reduce #(f %2) coll) nil) |
| 11:50 | sdegutis | So I'm guessing it's meant for this kind of thing: |
| 11:50 | sdegutis | (run! handle-request (incoming-requests)) |
| 11:51 | clgv | sdegutis: reducers equivalent of `dorun` is my guess |
| 11:52 | clgv | erm actually more like doseq but a function instead of a macro ;) |
| 11:53 | Bronsa | ,(run! println (reify clojure.lang.IReduceInit (reduce [_ f _] (loop [a 10] (when (pos? a) (f _ a) (recur (dec a))))))) |
| 11:53 | clojurebot | 10\n9\n8\n7\n6\n5\n4\n3\n2\n1\n |
| 11:53 | Bronsa | justin_smith: ^ a stupid example of run! w/o any coll realization |
| 11:54 | sdegutis | I once heard that the primary use of macros in traditional Lisps is to not have to write (lambda ...) so much. |
| 11:54 | sdegutis | What's the primary use of macros in Clojure? |
| 11:54 | sdegutis | Bronsa: thats neat btw |
| 11:57 | justin_smith | Bronsa: thanks |
| 12:17 | Olajyd | Can I get a function such that (isAbbreviation("capture the flag","cptr”)) returns "aue the flag”? |
| 12:18 | gilliard | You mean to remove all the instances of the 2nd string from the first string? |
| 12:19 | Olajyd | yes |
| 12:19 | Olajyd | gilliard sure |
| 12:21 | Olajyd | gilliard,function call: (isAbbreviation "capture the flag" "cptr” ) ;=>"aue the flag” |
| 12:21 | Bronsa | ,(reduce (fn [s el] (.replaceFirst s (str el) "")) "capture the flag" "cptr") |
| 12:21 | clojurebot | "aue the flag" |
| 12:21 | gilliard | ,(apply str (filter (comp not (into #{} "cptr")) "capture the flag")) |
| 12:21 | clojurebot | "aue he flag" |
| 12:22 | Bronsa | gilliard: (filter (comp not f) x) is (remove f x) |
| 12:23 | Bronsa | he doesn't want all the elements removed though, just the first instance IIUC |
| 12:23 | gilliard | ,(apply str (remove (into #{} "cptr") "capture the flag")) |
| 12:23 | clojurebot | "aue he flag" |
| 12:23 | gilliard | Nice thanks Bronsa. |
| 12:24 | gilliard | Olajyd: you have choices :) |
| 12:24 | Olajyd | hahah |
| 12:24 | Olajyd | another tricky use case |
| 12:25 | Bronsa | gilliard: he wants "aue the flag", your solutions return "aue he flag" |
| 12:25 | Olajyd | isAbbreviation("capture the flag","hello") returns null :) |
| 12:26 | Olajyd | gilliard, isAbbreviation(String originalString,String abbreviation) If abbreviation is not valid, it returns null Otherwise, it returns a string of the characters that have been removed from originalString to make abbreviation |
| 12:27 | Bronsa | Olajyd: (defn abbr [original abbreviation] (reduce (fn [s el] (if (not (.contains s (str el))) (reduced nil) (.replaceFirst s (str el) ""))) original abbreviation)) |
| 12:55 | snowell | Is if-some just if-let with multiple bindings in its test? |
| 12:55 | snowell | I'm trying to grok what if-some does that if or if-let doesn't |
| 13:00 | ToxicFrog | snowell: if-some is if-let, but it takes the else branch only if the binding value is nil |
| 13:00 | ToxicFrog | ,(if-some [x false] :t :f) |
| 13:00 | clojurebot | :t |
| 13:00 | ToxicFrog | ,(if-let [x false] :t :f) |
| 13:00 | clojurebot | :f |
| 13:00 | ToxicFrog | Use it when you want any non-nil value, and "any" can include false. |
| 13:00 | snowell | Ah, that makes sense! |
| 13:01 | snowell | I thought it had something to do with (some) at first, and was confused :) |
| 13:01 | snowell | (inc ToxicFrog) ; Thanks! |
| 13:01 | lazybot | ⇒ 5 |
| 13:02 | snowell | OK, I see where it DOES have to do with (some). I speak before thinking. |
| 13:04 | ToxicFrog | snowell: Also relevant, some->, which is -> but aborts at the first nil. |
| 13:05 | pjstadig | i brushed off and updated chouser's code |
| 13:05 | pjstadig | 2008: http://n01se.net/paste/fZQ?pretty=no |
| 13:05 | pjstadig | 2015: http://i.imgur.com/m6dSDll.png |
| 13:06 | zerokarmaleft | that's sweet |
| 13:09 | clgv | pjstadig: hehe |
| 13:10 | pjstadig | i think it actually looks more of a contrast than it should. I think most of the Expr classes near the top, and Reader classes near the bottom existed in 2008. It's mostly the stuff in the middle that has changed |
| 13:11 | pjstadig | it doesn't include any of the classes that are generate from clojure code (like the gvec classes) |
| 13:11 | amalloy | snowell: 1.6 added a few "some"-flavored functions, which act like already-existing functions but only count nil as falsey, not even false |
| 13:12 | amalloy | that is, the only value that they consider to be falsey is nil |
| 13:20 | chouser | pjstadig: Thanks for doing that! |
| 13:20 | chouser | The older version was manually adjusted to reduce diagram size and complexity. |
| 13:21 | pjstadig | ah ok |
| 13:22 | pjstadig | chouser: it was interesting see the changes necessary to modernize the code |
| 13:22 | pjstadig | i have some old clojure lying around, but i don't think it's quite from that era |
| 13:22 | chouser | pjstadig: I'm sure. I've actually taken a crack or two at it before, but got bogged down, so thanks for finishing it up. |
| 13:23 | pjstadig | chouser: i can post it in a gist |
| 13:23 | chouser | ok. or a pull request if you want. ... it is a git repo, right? |
| 13:24 | pjstadig | chouser: maybe? i grabbed it from here https://groups.google.com/forum/#!topic/clojure/H42kG6_aKms |
| 13:26 | pjstadig | chouser: https://gist.github.com/pjstadig/bade0e5eb130c255669f |
| 13:28 | pjstadig | oh yeah, this code is much better :) https://github.com/Chouser/clojure-classes |
| 13:42 | noncom | did anyone use gorilla repl? |
| 13:45 | justin_smith | semi-offtopic - is there git wizardry that would help automate a merge in a situation where I have moved some code into a different git repo? |
| 13:46 | Olajyd | ,(defn abbr [original abbreviation] (reduce (fn [s el] (if (not (.contains s (str el))) (reduced nil) (.replaceFirst s (str el) ""))) original abbreviation)) |
| 13:46 | clojurebot | #'sandbox/abbr |
| 13:46 | sed-gnu-utils | ,abbr |
| 13:46 | clojurebot | #object[sandbox$abbr 0x7b887bd1 "sandbox$abbr@7b887bd1"] |
| 13:46 | sed-gnu-utils | ,(partial abbr) |
| 13:46 | clojurebot | #object[sandbox$abbr 0x7b887bd1 "sandbox$abbr@7b887bd1"] |
| 13:46 | Olajyd | ,(abbr ”capture the flag" "hello”) |
| 13:46 | clojurebot | #error {\n :cause "Unable to resolve symbol: ”capture in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: ”capture in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: ”captur... |
| 13:46 | sed-gnu-utils | ,(= abbr abbr) |
| 13:46 | clojurebot | true |
| 13:47 | sed-gnu-utils | ,(= (partial abbr) abbr) |
| 13:47 | clojurebot | true |
| 13:47 | justin_smith | Olajyd: your client is sending smart quotes |
| 13:47 | justin_smith | Olajyd: which are not valid clojure string delimiters |
| 13:47 | sed-gnu-utils | ,[,abbr, (partial, abbr, "foo"),], |
| 13:47 | clojurebot | [#object[sandbox$abbr 0x7b887bd1 "sandbox$abbr@7b887bd1"] #object[clojure.core$partial$fn__4515 0x28fb8a64 "clojure.core$partial$fn__4515@28fb8a64"]] |
| 13:48 | justin_smith | ,(abbr "capture the flag" "hello") |
| 13:48 | clojurebot | nil |
| 13:48 | justin_smith | ,(abbr "capture the flag" "cptr") |
| 13:48 | clojurebot | "aue the flag" |
| 13:49 | Olajyd | aite, thanks :) |
| 13:54 | breadmonster | Hi everyone. |
| 13:54 | R0B_ROD | hi breadmonster |
| 13:55 | breadmonster | I was thinking of diversifying languages, and someone recommended Clojure to me. |
| 13:55 | breadmonster | So just wondering if any of you have tips on how to get started. |
| 13:55 | sed-gnu-utils | What's an unthinkable alternative for removing an element from a seq than (->> seq (remove (partial = el))) |
| 13:55 | breadmonster | Also, how does clojure compare with Haskell? It's the only other programming language I know. |
| 13:56 | justin_smith | sed-gnu-utils: hiring Peruvian peasants to do it by hand |
| 13:56 | breadmonster | justin_smith: lol |
| 13:56 | justin_smith | breadmonster: he asked for "unthinkable" |
| 13:56 | wasamasa | breadmonster: I'd say it's more practical weren't it for haskell fanboys punching me for such accusations |
| 13:56 | breadmonster | wasamasa: Doesn't like the JVM stop you from using tail recursion? |
| 13:57 | wasamasa | breadmonster: see, it's started |
| 13:57 | breadmonster | lol no that was an honest question. |
| 13:57 | breadmonster | That said, Haskell has laziness as an issue. |
| 13:58 | sed-gnu-utils | justin_smith: technically correct |
| 14:00 | sed-gnu-utils | breadmonster: Clojure is neat, although I mostly like it for the native API to Datomic |
| 14:00 | wasamasa | breadmonster: tail recursion is how you do loops in clojure, duh |
| 14:00 | sed-gnu-utils | justin_smith: I'm running out of words for "good" in my thesaurus |
| 14:00 | wasamasa | breadmonster: you'll even get helpful compile errors if you try using recur in a non-tail position |
| 14:00 | breadmonster | Interesting. |
| 14:01 | breadmonster | Cool stuff. |
| 14:01 | sed-gnu-utils | justin_smith: in this case, good -> great -> fantastic -> unthinkable, via Oxford American Writer's Thesaurus |
| 14:01 | sed-gnu-utils | wasamasa: scheme is inherently inferior to Clojure |
| 14:01 | sed-gnu-utils | I WILL FIGHT YOU ABOUT THIS |
| 14:01 | wasamasa | sed-gnu-utils: fuck off |
| 14:02 | wasamasa | sed-gnu-utils: I've seen enough trolling by you on #emacs to know where that will lead |
| 14:02 | sed-gnu-utils | wasamasa: relax it was a joke |
| 14:02 | sed-gnu-utils | wasamasa: #clojure is a laid back and peaceful channel, enjoy it :) |
| 14:05 | sed-gnu-utils | Is there an alternative to map like (something f coll) that just runs (f el) and returns coll? |
| 14:05 | gfredericks | sed-gnu-utils: run! will do that but returns nil |
| 14:05 | justin_smith | (do (f el) coll) |
| 14:05 | gfredericks | (doto coll (->> (run! f))) |
| 14:05 | sed-gnu-utils | I'm hoping for something I can put inside of a ->> |
| 14:06 | gfredericks | you'd need a <- to get it back to single arrow position |
| 14:07 | amalloy | sed-gnu-utils: please stop changing your nick so that people like wasamasa who probably have sdegutis in their /ignore list don't have to keep adding to it |
| 14:07 | sed-gnu-utils | amalloy: haha s/wasamasa/me/ don't try to hide it dude |
| 14:08 | sdegutis | Happy? |
| 14:08 | amalloy | thanks |
| 14:08 | amalloy | atm you are in fact not on my /ignore list; i phase you in and out in case you stop doing stuff like threatening to fight people about scheme vs clojure |
| 14:11 | sdegutis | For the record, I haven't trolled in over a year. |
| 14:11 | justin_smith | sdegutis: I'm ignoring you for that, on principle, sorry |
| 14:11 | sdegutis | And it's pretty clear that my response to wasamasa was a good-hearted joke. |
| 14:11 | sdegutis | (That's not the right expression but I can't remember what it's supposed to be.) |
| 14:11 | wasamasa | writing is hard |
| 14:11 | blkcat | facetious? |
| 14:12 | sdegutis | No like light-hearted and friendly or something. |
| 14:13 | sdegutis | I work remotely, so I come here for socialization, to share brain teasers, and to help the occasional newb. The brain teasers are the most fun part tbh. |
| 14:21 | wink | Rough times in #clojure. If this keeps escalating at this pace... someone might write an angry tweet. /o\ |
| 14:22 | sdegutis | :D |
| 14:23 | wasamasa | phew, I don't use twitter |
| 14:23 | sdegutis | I suppose (map #(doto % (f))) works |
| 14:23 | wasamasa | ok, that's not quite right, I've got a novelty account I intended to use for a markov chain bot, but I dropped the project midways |
| 14:24 | sdegutis | In Haskell? |
| 14:24 | wasamasa | clojure of course |
| 14:24 | sdegutis | :D |
| 14:24 | sdegutis | src? |
| 14:24 | wasamasa | why else would I tell this channel |
| 14:24 | sdegutis | cuz it's relevant to the current conversation |
| 14:24 | wasamasa | well, it's mostly a copy of http://howistart.org/posts/clojure/1/ |
| 14:25 | sdegutis | nice |
| 14:25 | wasamasa | except that my sources weren't nearly as convenient for the suggested tweaks |
| 14:34 | sdegutis | fwiw, clojure.core/name isn't quite just a way to turn a symbol/keyword into a string... it's more like basename but for the / |
| 14:35 | gfredericks | sdegutis: http://hacklog.gfredericks.com/2013/08/10/clojure-overloads-the-term-namespace.html |
| 14:41 | wasamasa | heh, hacklog |
| 14:45 | sdegutis | gfredericks: nice |
| 14:45 | sdegutis | ,((juxt namespace name) :foo.bar/quux) |
| 14:45 | clojurebot | ["foo.bar" "quux"] |
| 14:45 | sdegutis | ,((juxt namespace name) 'foo.bar/quux) |
| 14:45 | clojurebot | ["foo.bar" "quux"] |
| 14:45 | sdegutis | ,((juxt namespace name) "foo.bar/quux") |
| 14:45 | clojurebot | #error {\n :cause "java.lang.String cannot be cast to clojure.lang.Named"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.Named"\n :at [clojure.core$namespace invokeStatic "core.clj" 1529]}]\n :trace\n [[clojure.core$namespace invokeStatic "core.clj" 1529]\n [clojure.core$namespace invoke "core.clj" -1]\n [clojure.core$juxt$fn__4498 i... |
| 14:45 | sdegutis | ha |
| 14:46 | sdegutis | Is there another way to write a literal symbol besides (quote foo)? |
| 14:47 | gfredericks | you're wondering about a syntax that would allow whitespace or something like that? |
| 14:47 | sdegutis | No, I just mean it feels a bit weird to use (quote), like it's a leaky abstraction from the compiler, an implementation detail we really shouldn't know about. |
| 14:47 | sdegutis | Unless of course the symbol is being used at compile-time or macro-expansion-time, in which case it makes perfect sense. |
| 14:48 | gfredericks | you can call the reader to get a symbol |
| 14:48 | sdegutis | But you still need to give it a string. |
| 14:48 | gfredericks | yep |
| 14:48 | sdegutis | ,(symbol "foo") |
| 14:48 | clojurebot | foo |
| 14:48 | sdegutis | Just like that. |
| 14:48 | gfredericks | no I don't think there's anything along the lines you're asking about |
| 14:48 | sdegutis | Okay. |
| 14:48 | sdegutis | Thanks gfredericks. |
| 14:48 | gfredericks | np |
| 14:51 | sdegutis | Is (apply concat) the best way to "flatten" a seq of seqs one-level deep? |
| 14:51 | sdegutis | OH! (flatten) exists! |
| 14:51 | sdegutis | I hadn't thought of that until I phrased my question, haha. |
| 14:51 | gfredericks | ~flatten |
| 14:51 | 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. |
| 14:51 | gfredericks | sdegutis: flatten is recursive, so apply concat is actually better |
| 14:51 | sdegutis | Touche :D |
| 14:52 | sdegutis | In this case though I think I can actually use mapcat, ha! |
| 14:52 | gfredericks | for is also good at this stuff |
| 14:53 | sdegutis | True, I use for a lot. Except inside ->> |
| 14:54 | sdegutis | Do yall often use `lein check` and put type hints everywhere it suggests? |
| 14:55 | pjstadig | if i want to avoid reflection, yes |
| 14:56 | gfredericks | or better you can set *warn-on-reflection* to true in the project.clj |
| 14:56 | pjstadig | but you can also tell leiningen to warn on reflection every time it compiles |
| 14:56 | gfredericks | which I almost never do |
| 14:56 | gfredericks | that can also be noisy since it warns about libraries as well |
| 14:56 | sdegutis | gfredericks: I like that! |
| 14:57 | sdegutis | Btw this is how I'm building my schema dynamically: https://gist.github.com/sdegutis/e5ee9f088d258186d6c0 |
| 14:57 | sdegutis | When I call (build-schema), it looks through all my code for (def ^:schema some-attributes [...]) and uses them. |
| 14:58 | Olajyd | can someone put me through `iterator-seq` in clojure? :| |
| 14:59 | sdegutis | I plan to do a similar thing with routes, where I would define one like (defn ^{:method :POST :route "/foo/bar"} my-route-handler [req] ...) |
| 14:59 | sdegutis | Olajyd: did you read this? |
| 14:59 | gfredericks | sdegutis: I just started using fnhouse, which is similar, and I love it |
| 14:59 | sdegutis | (doc iterator-seq) |
| 14:59 | clojurebot | "([iter]); Returns a seq on a java.util.Iterator. Note that most collections providing iterators implement Iterable and thus support seq directly. Seqs cache values, thus iterator-seq should not be used on any iterator that repeatedly returns the same mutable object." |
| 14:59 | sdegutis | gfredericks: never heard of it, will look it up, thanks |
| 14:59 | sdegutis | gfredericks: I had this idea a year ago but never had time to merge my branch with that (and fix the bugs) until now |
| 15:00 | Olajyd | sdegutis, a simpler explanation will do :) |
| 15:00 | gfredericks | sdegutis: fnhouse is especially good if you like prismatic/schema, which I do |
| 15:01 | sdegutis | Olajyd: Most likely you never need it, what makes you wonder if you need it? |
| 15:01 | sdegutis | gfredericks: I like it in theory but have never tried it. |
| 15:01 | sdegutis | gfredericks: oh, by the same people, cool |
| 15:02 | gfredericks | sdegutis: I think prismatic/schema starts to get really useful when you use coercers |
| 15:02 | sdegutis | I'm excited about alternatives to Compojure gaining popularity, I can't wait for Compojure's mindshare to die down. |
| 15:02 | sdegutis | coercers? |
| 15:03 | pjstadig | gfredericks: inc |
| 15:03 | gfredericks | which also works well with fnhouse; so e.g. I can say that a particular query param or uri-param is an integer, and it will get parsed for me |
| 15:03 | Olajyd | sedgutis, ok somebody used it `(iterator-seq it)` just wondering why though :) |
| 15:03 | pjstadig | especially if you're stuck with anemic data formats like JSON |
| 15:04 | sdegutis | amalloy_: that was the real reason I did /nick btw |
| 15:04 | sed-gnu-utils | Olajyd: got a link? |
| 15:04 | sed-gnu-utils | gfredericks: oh man that sounds awesome and super convenient |
| 15:05 | sed-gnu-utils | gfredericks: as long as the declaration is succinct, I'm sold |
| 15:05 | gfredericks | it's not too bad |
| 15:06 | sed-gnu-utils | Btw I like the idea of no global state, but to some extent vars and namespaces already are unavoidable global state. |
| 15:06 | gfredericks | not if they're constant |
| 15:07 | gfredericks | they're definitely potentially state, which is what code reloading is all about; but that's different from using them for your app's global state |
| 15:07 | Olajyd | sed-gnu-utils: was going through http://stackoverflow.com/questions/32207234/convert-from-clojure-lang-lazyseq-to-type-org-apache-spark-api-java-javardd/32211936#32211936 |
| 15:07 | sed-gnu-utils | That's part of what attracted me to Haskell, with its unified concept of non-stateful state and no distinction between compile time and runtime. |
| 15:07 | sed-gnu-utils | gfredericks: touche |
| 15:11 | xemdetia | wtf |
| 15:11 | sed-gnu-utils | xemdetia: ? |
| 15:25 | sed-gnu-utils | Whoa. Turns out my technique is super slow. |
| 15:27 | sed-gnu-utils | Ordinarily (build-schema) is only called once at start-up, but I forgot it runs at the beginning of each 700 of our tests. |
| 15:28 | justin_smith | oops forgot to ignore the other nicks |
| 15:30 | snowell | afaik my client resets the /ignore list on a restart :/ |
| 15:31 | amalloy | mine does too, and it's annoying, but also reminds me to give people a chance to change |
| 15:31 | snowell | You're far more optimistic than I :D |
| 15:34 | sed-gnu-utils | (defn ^:memoize foo [...] ...) should be a shortcut (def foo (memoize (fn [...] ...))) |
| 15:35 | sed-gnu-utils | justin_smith: lol |
| 15:36 | Bronsa | sed-gnu-utils: stop changing nicks. |
| 15:36 | sed-gnu-utils | Bronsa: this nick is legitimately easier for non-regulars to mentally parse and respond to correctly than sdegutis |
| 15:36 | sed-gnu-utils | time and time again they type "sdegutils" or "sedutis" etc |
| 15:37 | sed-gnu-utils | Probably 80% of them. |
| 15:49 | sed-gnu-utils | ,(concat [1] nil [2 3]) |
| 15:49 | clojurebot | (1 2 3) |
| 15:49 | sed-gnu-utils | cool |
| 16:24 | Olajyd | can somebody explain .swap with use cases? :| |
| 16:25 | sed-gnu-utils | Olajyd: you mean swap!? |
| 16:25 | sed-gnu-utils | Olajyd: have you read (doc swap!) |
| 16:25 | sed-gnu-utils | (doc swap!) |
| 16:25 | clojurebot | "([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in." |
| 16:26 | kavkaz | Is there a built in function for finding the first item in a sequence which returns logical true for a given function? |
| 16:26 | Olajyd | sed-gnu-utils: he used `#(.swap %)` |
| 16:26 | sdegutis | It's the same as JavaScript's = operator. |
| 16:26 | sdegutis | Olajyd: oh then it's just a Java method. |
| 16:26 | kavkaz | I thought it'd be more efficient than (first (filter f seq)) |
| 16:26 | sdegutis | kavkaz: that's the solution I keep going back to, and it's pretty efficient |
| 16:26 | oddcully | Olajyd: it calls the method .swap on the object. what is the object there? |
| 16:26 | kavkaz | sdegutis: Perhaps because of lazy sequences? |
| 16:26 | sdegutis | kavkaz: with lazy seqs it stops when you find it and doesn't consume the rest |
| 16:26 | sdegutis | yeah |
| 16:27 | kavkaz | I'm not too sure |
| 16:27 | kavkaz | oh i see |
| 16:27 | kavkaz | Thank you sdegutis |
| 16:27 | sdegutis | oddcully: it's % of course |
| 16:27 | sdegutis | ;) |
| 16:27 | sdegutis | kavkaz: btw I usually put them inside ->> like (->> coll (filter f) (first)) |
| 16:28 | sdegutis | Makes me feel like I'm using JavaScript or something. |
| 16:28 | Olajyd | oddcully, I’m guessing its an anonymous function that takes in input like [[“foo” “bar”] 1] |
| 16:28 | kavkaz | sdegutis: lol, the threading operators are something that I am yet to get used to. |
| 16:28 | kavkaz | Makes it more confusing for me personally but I could see why some people prefer them |
| 16:33 | oddcully | Olajyd: it is some java object and the method .swap is called on that object. if you want to know, what gets passed in there, you have to debug at least the (type %). |
| 16:34 | oddcully | Olajyd: if you can not give any hint on the object used here, you would have to guess from the params, that this might simply swap two elements |
| 16:38 | Olajyd | oddcully, well I saw this on stackoverflow: `(def rdd-idx (f/map-to-pair (.zipWithIndex rdd) #(.swap %)))` dont know if that helps :| |
| 16:41 | oddcully | i'd consult the spark/flambo man pages |
| 16:43 | Olajyd | I understand what the .zipWithIndex and map-to-pair will do though, I just dont understand the .swap :( |
| 16:45 | Olajyd | thanks oddcullly |
| 17:55 | Stalkr_ | Hi, I have a course about programming language concepts. Virtual machines, byte code, abstract syntax trees etc. We use F# for this, how well does Clojure work as an interpreter/compiler? How does it compare to F# or Haskell? I hope my question makes sense, this is very new stuff for me |
| 17:56 | Stalkr_ | I guess it comes down to using Clojure as a lexer/parser? |
| 17:57 | justin_smith | Stalkr_: clojure does not have an interpreter, and does not use the javac compiler, it compiles to jvm bytecode |
| 17:57 | justin_smith | Stalkr_: lisps do compilation a little differently |
| 17:57 | Stalkr_ | justin_smith: Sorry, I worded it wrong. I meant to use Clojure as a lexer, for my own language |
| 17:57 | justin_smith | as one, or as a language in which to write one? |
| 17:57 | hiredman | generally, if I am doing that sort of thing in clojure, the language I am implementing is also a lisp, so I often just use clojure's reader |
| 17:58 | Stalkr_ | justin_smith: Not sure I follow. Say I want to lex/parse C code, is Clojure suitable for that? |
| 17:58 | hiredman | clojure doesn't so much have a lexer or a parser, it has a reader, which you basically interact with like a some kind of json codec (if you used one of those in another lnaguage) |
| 17:59 | hiredman | there are some really neat clojure parsing libraries like instaparse which you can use for building parsers for whatever |
| 17:59 | amalloy | Stalkr_: you can of course write a lexer and a parser yourself in clojure |
| 17:59 | Stalkr_ | I haven't done anything like this, it's a course I am taking and interested in trying than something else than F# |
| 17:59 | Stalkr_ | trying something* |
| 17:59 | amalloy | using some library like hiredman says. note though that if you actually want to parse a .c file in an entirely standards-compliant way that is a lot of work |
| 17:59 | hiredman | it is true |
| 18:00 | amalloy | choosing a less warty language to parse would be a good idea, unless you specifically need to parse c |
| 18:00 | Stalkr_ | C was just an example, could be whatever. It would probably be my own little toy language |
| 18:01 | hiredman | https://github.com/hiredman/prubasic uses instaparse to parse a language not unlike basic |
| 18:01 | Stalkr_ | so basically any language can work as a lexer, FP is just great for interpreters/compilers? I just hear Haskell often when talking about compilers |
| 18:01 | amalloy | Stalkr_: clojure is a fine language for that, and haskell also has some great parsing libraries. i don't know about f# |
| 18:01 | hiredman | https://github.com/hiredman/prubasic/blob/master/src/prubasic/parser.clj instaparse takes a bnf like syntax |
| 18:02 | hiredman | Stalkr_: compilers are generally pipelines of transformations over graphs |
| 18:02 | hiredman | functional programming does pretty well at that |
| 18:03 | Stalkr_ | I see, I'll have to play around with Clojure when I understand more. First lecture tomorrow |
| 18:06 | sdegutis | hiredman: how has been your experience using instaparse? |
| 19:19 | seangrove | Ok, deep into personally unexplored territory |
| 19:19 | seangrove | I've gone to https://github.com/google/closure-compiler, cloned it, run `ant jar`, and now I have build/compiler.jar |
| 19:19 | seangrove | What's the process for getting lein/clojurescript to use that instead of whatever it's currently pulling in? |
| 19:37 | ebzzry | Where/how is #_ defined? |
| 19:48 | amalloy | ebzzry: in the reader, in LispReader.java |
| 19:51 | ebzzry | amalloy: aside from line 105, what else should I look at? |
| 19:52 | amalloy | ebzzry: note that 105 refers to a DispatchReader for #, and then there's a dispatchMacros with a DiscardReader for _ |
| 19:53 | ebzzry | amalloy: thanks! |
| 20:57 | rasmusto | whoops, I was relying on (set [1 2 3]) coming out ordered |
| 22:17 | sdegutis | haha |
| 22:17 | sdegutis | rasmusto: I think there is some kind of ordered set tho iirc |
| 22:17 | sdegutis | ,(distinct [1 2 2 3]) |
| 22:17 | clojurebot | (1 2 3) |
| 22:17 | sdegutis | yeah that works |
| 22:17 | justin_smith | ,#{3 21} |
| 22:17 | clojurebot | #{21 3} |
| 22:17 | justin_smith | err |
| 22:18 | justin_smith | ,#{3 2 1} |
| 22:18 | clojurebot | #{1 3 2} |
| 22:21 | bacon1989 | does that mean sets are stored as binary trees, or some variant? |
| 22:25 | mange | bacon1989: the default set is a hash-set, which is one of these https://en.wikipedia.org/wiki/Hash_array_mapped_trie |
| 22:27 | bacon1989 | oh neat |
| 22:27 | bacon1989 | so the characteristics of the set we're seeing is a result of the trie part? |
| 22:27 | bacon1989 | I just assumed a binary tree, since it's evaluating and storing the values in the order 3 2 1 |
| 22:27 | bacon1989 | but results in 1 3 2 |
| 22:28 | bacon1989 | so I figured it looks like... |
| 22:28 | bacon1989 | /\ |
| 22:28 | bacon1989 | 2 3 |
| 22:28 | bacon1989 | then |
| 22:28 | mange | I think it's more the hashing that's causing it. |
| 22:28 | mange | ,(map hash [1 2 3]) |
| 22:28 | clojurebot | (1392991556 -971005196 -1556392013) |
| 22:29 | bacon1989 | hmm |
| 22:29 | mange | If you want a binary tree, though, you can use sorted-set, which is a persistent red-black tree. |
| 22:30 | mange | ,(sorted-set 3 2 1) |
| 22:30 | clojurebot | #{1 2 3} |
| 22:31 | bacon1989 | ah ok |
| 22:33 | seangrove | Bronsa: Trying to use t.a.js, and get an error "resolve-var does not exist" with the latest version |
| 22:36 | seangrove | Bronsa: Seems to happen on `(require '[clojure.tools.analyzer.js :as a])` |
| 22:37 | amalloy | seangrove: gist a stacktrace: it'll provide information about what file contains the offending reference, at least |
| 22:40 | amalloy | my bet is on a version conflict between two libraries you depend on that both depend on tajs |
| 22:40 | amalloy | since tajs hasn't changed in 8 months |
| 22:40 | seangrove | amalloy: Likely, yes |
| 22:41 | seangrove | https://gist.github.com/sgrove/d5527266131a1c5135b6 |
| 22:42 | seangrove | This may be a slightly over-ambitious approach for what I'm trying to do actually |
| 22:45 | amalloy | yeah, i think you are just not using the latest version of tajs at all, since the form that is causing the problem in your stacktrace can't behave that way with the code on github |
| 22:45 | seangrove | Ok, perhaps backing up would be a good idea |
| 22:46 | seangrove | Let's say I have n-forms, the first is a ns-form, and then *probably* some top-level def forms. A file for the ns already exists, and maybe have code in it. |
| 22:47 | seangrove | I would like to know where I can insert the new forms such that dependencies will be satisfied |
| 22:50 | mordocai | My midje tests don't appear to be running. I just upgraded everything (all dependencies) and have been having trouble since. Any ideas? I get this output: https://www.refheap.com/108827 and here is my code: https://github.com/mordocai/mordocai.net |
| 22:50 | mordocai | I haven't done any clojure for a while so... |
| 22:50 | mordocai | I'm lost |
| 22:50 | seangrove | e.g. the new forms may reference existing vars in the file, so they need to be placed after those vars |
| 22:51 | seangrove | I guess that actually shouldn't be too bad |
| 22:52 | andyf_ | seangrove: You have some new forms you want to add to an existing source file, and you are hoping to use tools.analyzer.* lib to help you determine the earliest point in the file the new form can go such that it won't get an error when compiling the file? |
| 22:52 | seangrove | andyf_: Yeah, exactly |
| 22:53 | seangrove | Well, actually, any suggestions for taking a form and getting the fully qualified name of every vary in it? Probably any var that 1. isn't prefixed with a / and is not in t.a.* env is a ns-local var |
| 22:53 | seangrove | And I can just walk down the tree and build up a list of these, then scan the file for the location of the vars |
| 22:53 | andyf_ | Would always putting the new form at the end be correct, or can there be forms already in the file that depend upon the new form you are adding? |
| 22:54 | amalloy | seangrove: you think nobody ever uses :refer or :use? |
| 22:54 | seangrove | amalloy: You bastard |
| 22:55 | seangrove | andyf_: If they define new forms while simulataneously redefining existing forms, that gets tricky |
| 22:55 | seangrove | I'm working on adding persistence to this https://www.dropbox.com/s/pvpgprg5kzq8sy4/dato_live_editing_2.mp4?dl=0 |
| 22:55 | amalloy | i mean i know i do. (ns foo.blah (:require [clojure.java.jdbc :as jdbc :refer [with-db]])) or whatever, where i refer to the stuff that i think reads better without a ns prefix |
| 22:55 | mange | mordocai: I don't think you can nest your fact assertions, like [url status] => [url 200], inside the form like that. I think you'll have to use something more like (fact [url status] => [url 200]). |
| 22:56 | mange | I've not used Midje for a long time, though, so I could be remembering that incorrectly. |
| 22:56 | seangrove | Maybe I should just go smalltalk browser and do single-fn defs - feels like a cop-out though |
| 22:56 | seangrove | amalloy: Yeah, it's a good point |
| 22:56 | seangrove | amalloy: I assume t.a.* gives you sufficient info to figure that out though? |
| 22:56 | amalloy | ha, amusingly tajs itself makes liberal use of :refer |
| 22:57 | amalloy | seangrove: i assume so, yes, but the point is that whether a thing includes a / or not makes no difference if you are using tajs, because it's already figured that stuff out for you |
| 22:57 | seangrove | amalloy: Yeah, another well-made point |
| 22:57 | mordocai | mange: Hmmm... well it used to work 10 months ago :P. I'll try it with fact. |
| 22:58 | mordocai | Either that or I never got my tests working before |
| 22:58 | seangrove | amalloy: I guess this is an indication https://github.com/clojure/tools.analyzer.js#outdated that Bronsa already knows, added two weeks ago |
| 22:59 | mange | mordocai: I would be somewhat surprised if your tests used to work. I don't think Midje has ever done that sort of transformation. |
| 23:12 | mordocai | mange: So wrapping those tests with fact didn't work either, same output. I know that code is running because if a put a println right above the facts it works. Also, I know it used to work as the place I got my info from (a blog post, but that blog post seems down) has a github repo here: https://github.com/cjohansen/cjohansen-no that has it the same way. So.... idk. I might just use clojure.test instead and see if I can get it |
| 23:12 | mordocai | working. |
| 23:16 | mordocai | Yeah, I don't think midje was working properly. Probably setup wrong. In any case, clojure.test works fine. |
| 23:16 | mordocai | Pushing shortly if you are interested, but it is super simple |
| 23:19 | mange | Okay, so it seems midje doesn't report its failures into the normal clojure.test metrics stuff, so putting the (fact ...) wrapper around the assertions makes them print their own error output, but the clojure.test stuff still says no tests were run. |
| 23:19 | justin_smith | yeah, it's a one or the other thing, they aren't designed to work together |
| 23:21 | mange | I can now see that it's even mentioned on this page: https://github.com/marick/Midje/wiki/A-tutorial-introduction-for-Clojure.test-users, I just missed it on my earlier skim. |
| 23:26 | amalloy | you can just put your facts into a deftest (and you really should, i think it's gross that midje doesn't encourage that) |
| 23:26 | amalloy | (deftest whatever (fact (+ 1 1) => 2)) works fine i believe |
| 23:26 | justin_smith | oh, I had no idea |
| 23:27 | amalloy | at any rate that's something you should try; i may have an overoptimistic memory |
| 23:27 | justin_smith | hha |
| 23:28 | timothyw | does anyone know if/how I can get a lazy reduce? |
| 23:28 | timothyw | need to iterate / map / whatever, over a sequence where the current value needs the last calculation |
| 23:29 | timothyw | partition won't work, because each partitioned list won't know about any previous ones |
| 23:29 | timothyw | any ideas? |
| 23:29 | justin_smith | reductions |
| 23:29 | justin_smith | ,(reductions + (range)) |
| 23:29 | clojurebot | (0 1 3 6 10 ...) |
| 23:30 | timothyw | reductions does show intermediate results… but can a current iteration use a result from a previous one |
| 23:31 | justin_smith | umm, that is how it works |
| 23:31 | justin_smith | the first arg is the previous return value, the second is the next input in the in seq |
| 23:32 | timothyw | got it - that’s embarrasing :) |
| 23:32 | timothyw | lemme have a look |
| 23:32 | justin_smith | another example ##(reductions conj () (range)) |
| 23:32 | lazybot | Execution Timed Out! |
| 23:32 | justin_smith | ,(reductions conj () (range)) |
| 23:32 | clojurebot | (() (0) (1 0) (2 1 0) (3 2 1 0) ...) |
| 23:36 | justin_smith | timothyw: if you need to carry more than one value (like a total and a previous input), a common idiom is to use destructuring |
| 23:37 | timothyw | yeah, I just tried it out and reductions does exactly what I need |
| 23:37 | timothyw | I knew I was missing something |
| 23:37 | timothyw | and yes on the destructuring front |
| 23:38 | timothyw | that’ll make the code more readable |
| 23:38 | justin_smith | ,(reductions (fn [[total prev] n] [(str total prev n) n]) ["" ""] '[a b c d e f g]) |
| 23:38 | clojurebot | (["" ""] ["a" a] ["aab" b] ["aabbc" c] ["aabbccd" d] ...) |
| 23:38 | justin_smith | wait, no |
| 23:38 | justin_smith | ,(reductions (fn [[total prev] n] [(str prev total n) n]) ["" ""] '[a b c d e f g]) |
| 23:38 | clojurebot | (["" ""] ["a" a] ["aab" b] ["baabc" c] ["cbaabcd" d] ...) |
| 23:39 | timothyw | far out… |
| 23:39 | justin_smith | ,(reductions (fn [[total prev] n] [(str total n prev) n]) ["" ""] '[a b c d e f g]) |
| 23:39 | timothyw | ,(+ 1 1) |
| 23:39 | clojurebot | (["" ""] ["a" a] ["aba" b] ["abacb" c] ["abacbdc" d] ...) |
| 23:39 | clojurebot | 2 |
| 23:39 | justin_smith | that one has musical patterns ^ |
| 23:40 | timothyw | niiice - I thought clojurebot was a user |
| 23:40 | justin_smith | a very special one :) |
| 23:40 | timothyw | yes, exactly, lol!! |