2015-07-21
| 00:02 | crocket | I just looked at lazybot code, and it doesn't provide a sandboxed environment for plugins. |
| 00:02 | justin_smith | crocket: it has a sandboxed eval |
| 00:03 | justin_smith | &(System/exit 0) |
| 00:03 | lazybot | java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "exitVM.0") |
| 00:03 | crocket | However, developers will only accept plugins in the 'core' if it doesn't go beyond the boundary of a plugin. |
| 00:23 | kavkaz | After using the REPL I feel like putting a right bracket after every sentence I type |
| 00:23 | kavkaz | whether it be IRC or SMS on my phone |
| 00:27 | rhg135 | (like this) |
| 00:29 | kavkaz | rhg135: yes |
| 00:30 | kavkaz | In some example code in a book about clojure, I'm seeing the character & being used like this: &{} |
| 00:30 | rhg135 | (not (ready-for? world this)) |
| 00:30 | kavkaz | what does this mean? |
| 00:30 | kavkaz | I know #{} is a set literal |
| 00:30 | kavkaz | but what does & mean in this context? |
| 00:30 | kavkaz | I couldn't find the character on the clojure cheat sheet. |
| 00:31 | rhg135 | De structuring |
| 00:31 | justin_smith | kavkaz: ##((fn [&{a :a}] (inc a)) :a 1) |
| 00:31 | lazybot | ⇒ 2 |
| 00:31 | justin_smith | & indicates that all following arguments are collected |
| 00:31 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: indicates in this context |
| 00:31 | justin_smith | :P |
| 00:32 | justin_smith | and &{ ... } means it will be collected into a key/value hash map |
| 00:32 | rhg135 | lazybot: disappointed |
| 00:32 | justin_smith | most people advise against using &{} actually |
| 00:34 | crocket | clojure 1.7 has new features like transducers, reader conditionals, warn on boxed math, update, and run!. |
| 00:36 | rhg135 | I'm excited for 1.8 |
| 00:41 | kavkaz | justin_smith: Thank you, I'm starting to get it |
| 00:41 | kavkaz | I've started clojure and functional programming a couple days ago, so it's taking some careful looking at |
| 00:41 | kavkaz | justin_smith: Why do most people advise against it? |
| 00:42 | kavkaz | It's just a map right? |
| 00:42 | justin_smith | kavkaz: a common thing to do in clojure is write a function that takes the same args, does some work, then calls the original function |
| 00:42 | kavkaz | sorry hashmap |
| 00:42 | justin_smith | this is harder to do with & {} |
| 00:43 | justin_smith | so, unless the usual usage of & (where you can use apply), you are stuck building the call by hand, or writing "mapply" or something |
| 00:43 | justin_smith | it's inconvenient |
| 00:44 | kavkaz | justin_smith: How would you do the example code you showed me without &{} |
| 00:44 | kavkaz | ? |
| 00:44 | kavkaz | I'm just curious because I'm new to clojure |
| 00:45 | justin_smith | ,((fn [{a :a}] (inc a)) {:a 41}) |
| 00:45 | clojurebot | 42 |
| 00:45 | justin_smith | in this case, the args are in an actual explicit hash-map |
| 00:46 | justin_smith | which means that you can use the hash-map to modify the args before calling the original (if you were extending it somehow) |
| 00:48 | kavkaz | justin_smith: Okay, I see, thank you |
| 00:48 | kavkaz | I'll just have to keep coding and reading this book and the documentation lol |
| 00:54 | kavkaz | justin_smith: Oh actually, I've been looking at & in the context of the parameter vector |
| 00:54 | justin_smith | kavkaz: yes. That's where it is used. |
| 00:55 | kavkaz | Oh true |
| 00:57 | crocket | http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming |
| 00:57 | kavkaz | well in the example it was [a b & { <map> } |
| 00:57 | crocket | justin_smith, Can you tell me more about sandboxed eval? |
| 00:58 | kavkaz | [a b & { <map> }] |
| 00:58 | justin_smith | kavkaz: sure, same as the other examples, except the a b part |
| 00:58 | justin_smith | crocket: I'm about to turn in for the night actually |
| 00:59 | kavkaz | After reading some documentation i thought the use of the ampersand in this case was [a b & more] |
| 00:59 | crocket | clojail |
| 00:59 | justin_smith | kavkaz: the a and b are optional |
| 00:59 | kavkaz | where more would be Nil if the passed parameters were only a and b |
| 00:59 | crocket | It uses clojail. |
| 00:59 | kavkaz | but anyways I'll keep looking into it |
| 00:59 | kavkaz | thank you justin_smith |
| 00:59 | justin_smith | and "more" is handled differently if it's a hash-map |
| 01:03 | kavkaz | good night guys |
| 01:04 | crocket | clojail is messy. |
| 01:04 | crocket | It requires ~/.java.policy |
| 01:07 | tolstoy | Is there an implementation of the ~ operator in Clojure somewhere? |
| 01:08 | tolstoy | bit-complement? |
| 01:10 | TEttinger | tolstoy: the bit-??? fns do pretty much everything bit-related. Do you mean ~ in... which language? |
| 01:10 | tolstoy | Python. |
| 01:10 | TEttinger | what does it do in Python? I'm not a python guy |
| 01:10 | tolstoy | Basically, swap all 1 bits for 0 bits. |
| 01:10 | TEttinger | ah |
| 01:10 | TEttinger | uh |
| 01:10 | TEttinger | hang on |
| 01:11 | tolstoy | I'm porting some code, so that's what's catching me up. |
| 01:11 | TEttinger | that seems not very handy, unless it takes more than one arg |
| 01:11 | tolstoy | If I knew the exact size of the integer, I could just use bit-flip. |
| 01:11 | TEttinger | ,(bit-and 0 15) |
| 01:11 | clojurebot | 0 |
| 01:11 | tolstoy | seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B) |
| 01:12 | TEttinger | does it also swap all 0 bits for 1 bits? |
| 01:12 | tolstoy | I think so. |
| 01:12 | tolstoy | http://stackoverflow.com/questions/791328/how-does-the-bitwise-complement-operator-work |
| 01:13 | tolstoy | Oh. bit-not, maybe? |
| 01:13 | TEttinger | bit-not yeah |
| 01:13 | TEttinger | ,(bit-not 8) |
| 01:13 | clojurebot | -9 |
| 01:14 | tolstoy | Python: ~2 -> -3 |
| 01:14 | TEttinger | ,(bit-not -2r1000) |
| 01:14 | clojurebot | 7 |
| 01:14 | tolstoy | Clojure: (bit-not 2) -> -3 |
| 01:14 | tolstoy | ,(bit-not 2) |
| 01:14 | clojurebot | -3 |
| 01:14 | TEttinger | woo |
| 01:14 | tolstoy | Good enough to continue the struggle. |
| 01:14 | TEttinger | the 2r thing is handy in case you haven't used it |
| 01:15 | tolstoy | What is it? |
| 01:15 | TEttinger | r for radix, it's base 2 literal |
| 01:15 | TEttinger | you can actually use any radix from 2 to 36 |
| 01:15 | TEttinger | ,2r101101 |
| 01:15 | clojurebot | 45 |
| 01:15 | TEttinger | ,36rFUNZILLA |
| 01:15 | clojurebot | 1242216307918 |
| 01:16 | tolstoy | So, give me the base 2 number 101101? |
| 01:16 | tolstoy | And then the printer prints it in base 10. |
| 01:17 | tolstoy | That is very handy. |
| 01:17 | tolstoy | ,16rFFF0 |
| 01:17 | clojurebot | 65520 |
| 01:18 | crocket | It feels like a huge mistake to make namespace mutable. |
| 01:20 | TEttinger | tolstoy: if you want to print in base (2 to 36), do ##(Long/toString 1242216307918 36) |
| 01:20 | lazybot | ⇒ "funzilla" |
| 01:20 | TEttinger | tolstoy: if you want to print in base 2, do ##(Long/toBinaryString 1242216307918) |
| 01:20 | lazybot | ⇒ "10010000100111001110111001001110011001110" |
| 01:23 | crocket | ,(println "say bitch") |
| 01:23 | clojurebot | say bitch\n |
| 01:25 | crocket | How do I sandbox arbitrary code without ~/.java.policy? |
| 01:27 | TEttinger | I think the contents of java.policy can be added programmatically |
| 01:36 | crocket | Is into lazy by default? |
| 01:39 | crocket | Listen to one of rich hickey's greatest videos. https://www.youtube.com/watch?v=6mTbuzafcII |
| 01:58 | bja | into is strict |
| 02:00 | bja | err, eager |
| 02:36 | namra | someone using metrics-clojure-ring and can tell me what the rates mean for handling-time.METHOD events? |
| 02:36 | namra | the rate of requests/s for that method over 1/5/15min? |
| 04:42 | crocket | It feels as if eduction is similar to sequence. |
| 05:14 | crocket | Man, it is difficult to understand transducers... |
| 05:18 | kungi | Deraen: Ping! Could you help me for a second with my compojure.api code. I upgraded to compojure api 0.22.1 and tried the upload. But now I get the following error: No method in multimethod 'restructure-param' for dispatch value: :multipart-params |
| 05:19 | kungi | Deraen: For some reason the multimethod definition from compojure.api.meta is not loaded? |
| 05:29 | crocket | Does anyone know a decent transducer learning material? |
| 05:52 | crocket | Ok, map returns a transducer. A transducer is passed another transducer or a reducing function to create another reducing function. |
| 05:52 | crocket | fn in fn in fn |
| 05:55 | crocket | This is a brain massage. |
| 06:05 | sandbags | Is there anyone who can help me with lein-wsimport (yes may god have mercy on my soul, SOAP) and a problem I am having enabling external scheme (error 'chema_reference: Failed to read schema document 'xjc.xsd', because 'file' access is not allowed due to restriction set by the accessExternalSchema property'). I've tried specifying :jvm-opts ["-Djavax.xml.accessExternalSchema=all"] in my project.clj which is - i think - the right way |
| 06:05 | sandbags | to solve this but no dice. Help! |
| 06:06 | sandbags | project.clj & full error here https://gist.github.com/mmower/78a1b440ffce7035832b |
| 06:10 | sandbags | i wonder if the problem is that wsimport is not being run with the jvm options... i've no idea how that bit works |
| 06:21 | sandbags | lein-wsimport is calling WsImport#doMain so, presumably, will inherit JVM opts so this should work |
| 06:30 | sandbags | frak... according to (System/getProperty "javax.xml.accessExternalSchema") it is set to "all" ... :-( |
| 06:30 | sandbags | sorry for the stream of consciousness... obv nobody here with any insight into wsimport and probably (just as I would have been) little interest :) |
| 06:31 | crocket | Can anyone help me understand transducer step arity? |
| 06:31 | crocket | When is it called? |
| 06:33 | crocket | Ah |
| 06:33 | crocket | ok |
| 06:33 | crocket | Completion arity in transducer feels like a boiler plate, doesn't it? |
| 06:43 | crocket | I think I found a bug in completing. |
| 06:43 | crocket | completing doesn't add 0 arity to a reducing function. |
| 06:44 | crocket | sdg |
| 06:44 | crocket | - |
| 06:50 | crocket | Ouch |
| 07:59 | diyfupeco | Is there a way to automatically load new code when something changed on disk? |
| 08:00 | diyfupeco | (using leiningen) |
| 08:05 | crocket | Is it ok to not define a 0 arity in a transducer? |
| 08:06 | wasamasa | diyfupeco: environments like figwheel do that kind of thing |
| 08:06 | crocket | ,(doc completing) |
| 08:06 | clojurebot | "([f] [f cf]); Takes a reducing function f of 2 args and returns a fn suitable for transduce by adding an arity-1 signature that calls cf (default - identity) on the result argument." |
| 08:07 | justin_smith | oh, that's very nice |
| 08:07 | crocket | completing is not going to work because a transducer requires a 0-arity signature. |
| 08:08 | crocket | I understand completing as a way to convert a reducing function into a transducer. |
| 08:09 | justin_smith | it addresses the common case where you have an accumulator that holds things other than your result, to simplify getting the part of the accumulator you actually want in the end |
| 08:10 | crocket | ??? |
| 08:10 | lazybot | crocket: How could that be wrong? |
| 08:11 | justin_smith | crocket: often when I use reduce, the accumulator holds other values along with the actual result |
| 08:11 | justin_smith | so I end up needing another function which gets the part I actually want out of the accumulator at the end |
| 08:14 | crocket | What is the accumulator? |
| 08:14 | crocket | You mean the reducing function? |
| 08:14 | justin_smith | ,(reduce (fn [[runs run] v] (if (= v (peek run)) [runs (conj run v)] [(conj runs run) []])) [[] []] [:a :a :b :b :b :b :c :c :a :d :d]) |
| 08:14 | clojurebot | [[[] [] [] [] [] ...] []] |
| 08:14 | justin_smith | err |
| 08:15 | justin_smith | crocket: the first arg to the reducing function is the accumulator |
| 08:15 | crocket | ok |
| 08:15 | crocket | initial value |
| 08:15 | crocket | Anyway, a transducer created by completing won't serve as a general transducer. |
| 08:16 | crocket | I am not sure when the 0-arity signature is used in a transducer. |
| 08:16 | justin_smith | ,(reduce (fn [[runs run] v] (if (= v (peek run)) [runs (conj run v)] [(conj runs run) [v]])) [[] []] [:a :a :b :b :b :b :c :c :a :d :d]) |
| 08:16 | clojurebot | [[[] [:a :a] [:b :b :b :b] [:c :c] [:a]] [:d :d]] |
| 08:17 | justin_smith | that needs a final step, where [:d :d] is conj'd on the end |
| 08:18 | crocket | Your example is hard to read. |
| 08:21 | crocket | justin_smith, Can you tell me when the 0-arity signature is used in transducers? |
| 08:35 | justin_smith | crocket: it is mentioned by the doc string for transduce |
| 08:36 | justin_smith | ,(transduce identity (completing (fn [[runs run] v] (if (= v (peek run)) [runs (conj run v)] [(conj runs run) [v]]))) [[] []] [:a :a :b :b :b :b :c :c :a :d :d]) |
| 08:36 | clojurebot | [[[] [:a :a] [:b :b :b :b] [:c :c] [:a]] [:d :d]] |
| 08:38 | justin_smith | completing adds a 1-arg arity |
| 08:39 | justin_smith | crocket: I don't know where this 0-arg is that you are talking about |
| 08:39 | crocket | ,(doc transduce) |
| 08:39 | clojurebot | "([xform f coll] [xform f init coll]); reduce with a transformation of f (xf). If init is not supplied, (f) will be called to produce it. f should be a reducing step function that accepts both 1 and 2 arguments, if it accepts only 2 you can add the arity-1 with 'completing'. Returns the result of applying (the transformed) xf to init and the first item in coll, then applying xf to that result and ... |
| 08:39 | crocket | transduce avoids using 0-arity signature. |
| 08:39 | justin_smith | where is the 0 arity signiture you keep mentioning? |
| 08:39 | crocket | By calling (f) directly. |
| 08:40 | crocket | justin_smith, http://clojure.org/transducers#toc8 |
| 08:41 | justin_smith | crocket: OK. It's used to create an initial value for the transduce when none is explicitly supplied. Like it says. |
| 08:41 | crocket | justin_smith, https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L7323 |
| 08:42 | kwladyka | What about sets performance vs vectors? |
| 08:42 | kwladyka | add/remove first/last positions |
| 08:42 | crocket | justin_smith, https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6566 |
| 08:42 | justin_smith | kwladyka: sets do not have a "first" or "last" position |
| 08:42 | justin_smith | kwladyka: they are not ordered |
| 08:43 | justin_smith | crocket: like I said, the docs are clear now that you link them, it creates the initial value for transduce |
| 08:43 | kwladyka | ,(first #{1 2}) |
| 08:43 | clojurebot | 1 |
| 08:44 | justin_smith | ,(first #{1 2 3 4 5 6 7 8 9 10}) |
| 08:44 | clojurebot | 7 |
| 08:44 | justin_smith | first will return a value, it will not return the first item, because there is no such thing |
| 08:44 | kwladyka | so when i will use it with loop and recur and use first and rest it will work or not? |
| 08:44 | justin_smith | definitely not, no |
| 08:45 | kwladyka | so bad |
| 08:45 | justin_smith | I mean maybe by accident, depending on what you are trying to do... |
| 08:45 | justin_smith | but you can't count on any particular item being the first without relying on implementation details |
| 08:45 | Wild_Cat | kwladyka: if you want to iterate on the entire contents of a set, use map |
| 08:45 | justin_smith | kwladyka: actually, first and rest should split one item off... |
| 08:46 | kwladyka | but... if first always return the same element (not exactly first) rest should return always the rest? |
| 08:46 | justin_smith | yes, that's true |
| 08:46 | crocket | The doc forgot to mention that completing also adds 0-arity signature. |
| 08:46 | justin_smith | the order is just weird and undefined |
| 08:47 | kwladyka | i don't care about order too much, but i guess performance of sets should be as good as vectors? |
| 08:47 | justin_smith | they are slower |
| 08:47 | crocket | I think completing should be used as (partial completing f) since cf is the reducing function. |
| 08:47 | kwladyka | do you know any statistic? I can't find information liek that |
| 08:48 | Wild_Cat | kwladyka: sets are O(1) for insertion, but with a higher constant than vectors |
| 08:48 | Wild_Cat | kwladyka: if you don't explicitly care about the uniqueness constraint, a set will be slower than a vector |
| 08:49 | kwladyka | anyway... i will do algorithm and if it will be to slow i will change data structure |
| 08:49 | justin_smith | kwladyka: runnint criterium now, will share the results when done |
| 08:50 | crocket | Now, completing doesn't seem to make a valid transducer. |
| 08:50 | Wild_Cat | that said, the fact that you struggle with understanding the very basic performance profiles of these data structures tells me that you're not writing something performance-critical enough to care about the difference. Just use whatever is the most logical for your use case and disregard the performance aspect. |
| 08:51 | kwladyka | Wild_Cat, but it is always good occasion to learn something more, like a basic performance :) |
| 08:52 | justin_smith | vectors are about 10x faster for appending https://www.refheap.com/106778 |
| 08:53 | kwladyka | i also see very good side of not mutable data, all things should take less memory |
| 08:53 | kwladyka | justin_smith, thank you |
| 08:56 | justin_smith | it's really sad that I can tell from the noise floor on my monitors when criterium is done running |
| 08:56 | justin_smith | haha |
| 08:56 | justin_smith | when the CPU is not working as hard the timbre changes |
| 08:58 | justin_smith | kwladyka: paste updated, the ratio gets closer with smaller collections (because some of the shared constant time costs become a bigger part of the resulting runtime I guess) https://www.refheap.com/106778 |
| 09:37 | crocket | justin_smith, I figured out that completing is not meant to produce a transducer. |
| 09:37 | crocket | https://groups.google.com/forum/#!topic/clojure/6cnVMUe5ALE |
| 09:39 | crocket | This is really ugly. |
| 09:39 | diyfupeco | thanks wasamasa |
| 09:41 | crocket | Is there a macro for writing a transducer concisely? |
| 09:42 | crocket | or a function for doing so? |
| 09:43 | snowell | crocket: Leaving out the final argument to a sequence function call (map, filter, etc) returns a transducer |
| 09:43 | snowell | You can comp transducers together to create one that does multiple things |
| 09:46 | crocket | snowell, Is there a transducer that drops key-val pairs with nil vals in a map? |
| 09:47 | snowell | I would think (remove #(nil? (val %))) should work |
| 09:49 | snowell | Heh, or even better… (filter val) |
| 09:49 | snowell | ,(filter val {:a 1 :b 2 :c nil :d 4 :e 5 :f nil}) |
| 09:49 | clojurebot | ([:a 1] [:b 2] [:d 4] [:e 5]) |
| 09:50 | snowell | If you want it to be a map, which of course you would, you could (comp (filter val) (into {})) |
| 09:54 | crocket | snowell, On https://www.refheap.com/106782 , I rewrote assoc-in-cond2 as assoc-in-cond with transduce. |
| 09:57 | snowell | And it's not working? |
| 09:57 | crocket | It does work. |
| 09:57 | crocket | Can you think of a more concise way to write assoc-in-cond? |
| 09:58 | crocket | snowell, ^^ |
| 09:59 | crocket | I think the function in completing could be written more conscisely. |
| 09:59 | snowell | I'm a relative newb compared to others here, so no I can't :D |
| 10:00 | snowell | I doubt I'd have gotten it THAT concise to begin with! |
| 10:07 | crocket | Is there a function that detects non-sequential value and turns it into a sequence? |
| 10:07 | crocket | A transducer is even better. |
| 10:07 | crocket | Ah |
| 10:08 | crocket | map is a transducer. |
| 10:08 | crocket | like (seqify 3) == '(3) |
| 10:08 | crocket | (seqify '(3)) == '(3) |
| 10:10 | crocket | ,(seq :3) |
| 10:11 | clojurebot | #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 528]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 528]\n [clojure.lang.RT seq "RT.java" 509]\n [clojure.core$seq__4126 invoke "core.clj" 135]\n [sand... |
| 10:14 | sveri | Hi, I want to insert something like {%if toread.done = 1 %}checked{% endif %} into a hiccup form, is there a way to do that? |
| 10:16 | hyPiRion | sveri: (if (= (:done toread) 1) "checked") ? |
| 10:16 | hyPiRion | I have no idea what toread is, might want to use (.done toread) instead |
| 10:17 | sveri | hyPiRion: no, I mean the string: "{%if toread.done = 1 %}checked{% endif %}" into a hiccup form which generates <input ... {%if toread.done = 1 %}checked{% endif %} /> |
| 10:17 | sveri | sorry for being unclear |
| 10:17 | justin_smith | sveri: hiccup forms are just clojure data structures, so there's as many ways to generate that as you like |
| 10:18 | justin_smith | sveri: so you have a post-processor over your hiccup output? |
| 10:19 | sveri | yea, I generate selmer html templates with hiccup |
| 10:21 | sveri | justin_smith: one way would be enough for me :D I am using hiccup like this now [:input {:key "val"} "string"] which generates <input "key"="val">string</input> but as "{%if toread.done = 1 %}checked{% endif %}" is no key value pair I am a bit stuck |
| 10:22 | justin_smith | sveri: yeah, when I said that I thought you were talking about generating html |
| 10:22 | justin_smith | and of course that's not html |
| 10:23 | crocket | Is there a way to map over only values in a map? |
| 10:23 | sveri | justin_smith: true |
| 10:23 | sveri | ok, so I generate selmer templates |
| 10:23 | crocket | ,(map #(update % 1 name) {:a :b :c :d}) |
| 10:23 | clojurebot | ([:a "b"] [:c "d"]) |
| 10:23 | justin_smith | sveri: my sad suspicion is you won't be able to do that because hiccup was never intended to be a general purpose renderer that could do non-html output |
| 10:24 | sveri | justin_smith: that's my assumption too after reading the docs, just wanted to make sure I am not missing anything |
| 10:24 | justin_smith | ,(map name (vals {:a :b :c :d :e :f}) |
| 10:24 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 10:24 | hyPiRion | sveri: I've tried to unescape html into hiccup in the past without luck |
| 10:24 | justin_smith | ,(map name (vals {:a :b :c :d :e :f})) |
| 10:24 | clojurebot | ("b" "d" "f") |
| 10:24 | justin_smith | ,(into {} (map #(update % 1 name) {:a :b :c :d :e :f})) |
| 10:25 | clojurebot | {:a "b", :c "d", :e "f"} |
| 10:25 | crocket | ,(into {} (map #(update % 1 name)) {:a :b :c :d}) |
| 10:25 | clojurebot | {:a "b", :c "d"} |
| 10:26 | crocket | I can't find a way to write it more concisely. |
| 10:28 | crocket | Is there a way to write https://www.refheap.com/106785 more concisely? |
| 10:30 | sveri | thanks everyone |
| 10:39 | crocket | ,(reduce #(+ %2) nil [1 2 3]) |
| 10:39 | clojurebot | 3 |
| 10:39 | crocket | How does it return nil? |
| 10:39 | crocket | oops |
| 10:42 | perplexa | ¯\_(ツ)_/¯ |
| 10:42 | justin_smith | perplexa: I really wish it was possible to name a function that |
| 10:42 | perplexa | haha |
| 10:42 | perplexa | isn't it? |
| 10:43 | oddcully | you cant? |
| 10:43 | justin_smith | it has parens in it |
| 10:43 | justin_smith | one moment, faking it |
| 10:43 | oddcully | there are for sure some utf-8 parens out there in the wild |
| 10:43 | perplexa | my repl strips the ツ :( |
| 10:44 | justin_smith | the harder part is the \ I think |
| 10:45 | justin_smith | I guess you could just fake the \ and the ( ) with unicodes |
| 10:45 | blkcat | #clojure, solving the important problems :P |
| 10:45 | justin_smith | the result should be (defmacro \_(ツ)_/¯ [& boxy] `(try ~@body (catch Throwable t :WHATEVER))) |
| 10:46 | justin_smith | err, body, whatever |
| 10:47 | kavkaz | hey justin_smith |
| 10:48 | justin_smith | yes? |
| 10:50 | kavkaz | just saying hello |
| 10:50 | justin_smith | oh, hi |
| 10:53 | wasamasa | justin_smith: now we know what's on your mind |
| 11:04 | justin_smith | ,(defmacro ¯\_❨ツ❩_/¯ [& bo `(try ~@body (catch Throwable t# :ok))) |
| 11:04 | clojurebot | justin_smith: Pardon? |
| 11:04 | justin_smith | :P |
| 11:04 | justin_smith | the unicode I used messes with my terminals |
| 11:05 | Bronsa | (defmacro (╯°□°)╯︵ ┻━┻ [& body] `(throw (Exception.))) |
| 11:06 | gfredericks` | ,(defmacro (╯°□°)╯︵ ┻━┻ [& body] `(throw (Exception. ~(pr-str &form)))) |
| 11:06 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 11:06 | Bronsa | ah, the open paren :( |
| 11:06 | gfredericks` | the sideways one? |
| 11:07 | justin_smith | yeah, I used a doppleganger |
| 11:07 | Bronsa | ,(defmacro ❨╯°□°)╯︵ ┻━┻ [& body] `(throw (Exception. ~(pr-str &form)))) |
| 11:07 | clojurebot | #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Symbol"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6644]}\n {:type java.lang.IllegalArgumentException\n :message "Do... |
| 11:07 | justin_smith | or are those already doppleganger parens? |
| 11:07 | Bronsa | ,(defmacro ❨╯°□°)╯︵┻━┻ [& body] `(throw (Exception. ~(pr-str &form)))) |
| 11:07 | clojurebot | #'sandbox/❨╯°□°)╯︵┻━┻ |
| 11:07 | Bronsa | there |
| 11:08 | gfredericks` | ,(❨╯°□°)╯︵┻━┻ whatever I don't even) |
| 11:08 | clojurebot | #error {\n :cause "(❨╯°□°)╯︵┻━┻ whatever I don't even)"\n :via\n [{:type java.lang.Exception\n :message "(❨╯°□°)╯︵┻━┻ whatever I don't even)"\n :at [sandbox$eval96 invoke "NO_SOURCE_FILE" -1]}]\n :trace\n [[sandbox$eval96 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.java" 6755]\n [clojure.core$eval invoke "core.clj |
| 11:08 | gfredericks` | perfect |
| 11:08 | Bronsa | heh |
| 11:08 | justin_smith | sweet |
| 11:08 | gfredericks` | (clojure.string/join " " (map pr-str &form)) might be slightly better |
| 11:23 | crocket | Can anyone write https://www.refheap.com/106785 more concisely? |
| 11:24 | crocket | Can I write (fn [m [keys val]] (assoc-in m keys val)) more concisely? |
| 11:31 | crocket | #(apply assoc-in %1 %2) can be done, but this is confusing. |
| 11:35 | gfredericks` | I am using node with cljs and I don't know what I'm doing |
| 11:35 | gfredericks` | debugging is hard |
| 11:37 | gfredericks` | I don't know how to get a cljs repl |
| 11:40 | crocket | gfredericks`, Are you writing a command line app? |
| 11:43 | justin_smith | gfredericks`: you can get a cljs repl with the cljs standalone jar |
| 11:45 | gfredericks` | justin_smith: does that use rhino? |
| 11:45 | gfredericks` | crocket: developing a library |
| 11:45 | gfredericks` | it's not a webby library so I want to avoid browsers if I can |
| 11:49 | crocket | webby? |
| 11:52 | gfredericks` | has nothing to do with doms or ajax |
| 11:55 | justin_smith | gfredericks`: hmm, not sure actually |
| 11:56 | csd_ | Hello-- If I have two successive calls to >! or >!! to the same channel, is order of delivery guaranteed? |
| 11:56 | justin_smith | gfredericks`: https://github.com/clojure/clojurescript/wiki/REPL-Options |
| 11:57 | justin_smith | csd_: in terms of control flow in your block of code, it will go start to end. I am not sure if there are strong guarantees of channels being ordered? |
| 11:58 | gfredericks` | yep looks like `lein test` can't find .cljc files |
| 11:58 | gfredericks` | to the githubmobile! |
| 11:59 | justin_smith | gfredericks`: yeah, I ran into this a few times (same issue with eastwood) |
| 11:59 | csd_ | justin_smith: yeah so if one >! is called before another, is it guaranteed to be delivered first too? |
| 11:59 | justin_smith | gfredericks`: I linked to the wrong page before, this is the right one https://github.com/clojure/clojurescript/wiki/Running-REPLs |
| 11:59 | csd_ | curious about both >! and >!! |
| 11:59 | gfredericks` | justin_smith: no github issue for lein yet that you know of? |
| 12:00 | justin_smith | csd_: it will be delivered first because the next one won't be run until the first one is |
| 12:00 | justin_smith | gfredericks`: definitely an issue, I forget the details |
| 12:00 | justin_smith | something about bultitude? |
| 12:00 | csd_ | ok thanks |
| 12:01 | justin_smith | gfredericks`: that wiki page shows separate config for node repl, rhino repl, etc. |
| 12:01 | Legendary_Linux | Hey so I'm entirely new to clojure and clojurescript, but I want to learn. Anyone know of some good tutorials to help me learn? A syntax guide would be awesome to start. |
| 12:02 | justin_smith | syntax? we don't need no stinking syntax! |
| 12:02 | justin_smith | Legendary_Linux: clojure.org has great docs for a start |
| 12:02 | justin_smith | for the super basic stuff |
| 12:03 | Legendary_Linux | I did find this, which was sort of helpful. http://clojurescriptkoans.com/ |
| 12:03 | justin_smith | Legendary_Linux: for exercises, 4clojure is great too |
| 12:03 | justin_smith | http://www.4clojure.com/ |
| 12:03 | Legendary_Linux | justin_smith: Thanks. |
| 12:04 | justin_smith | just be aware the difficulty is not all in numeric order, feel free to start skipping eventually |
| 12:04 | justin_smith | it will suggest "try X next" and X isn't always the best next puzzle to try |
| 12:05 | gfredericks` | justin_smith: this repl stuff looks promising, thanks |
| 12:05 | justin_smith | Legendary_Linux: depending on how much programming experience you have, there is also clojure from the ground up by aphyr, and clojure for the brave and true |
| 12:05 | justin_smith | gfredericks`: yeah, thankfully dnolen realized how tangled the world of cljs tooling got and prioritized making some (relatively) simple options available. Which is awesome. |
| 12:05 | justin_smith | (inc dnolen) |
| 12:05 | lazybot | ⇒ 23 |
| 12:08 | Legendary_Linux | I have history with C, C++, and Java. That was a few years ago, though. More recently I've been doing PHP, JS, and Node.js |
| 12:09 | justin_smith | yeah, clojure from the ground up would likely be a bit too introductory then |
| 12:10 | justin_smith | though clojure for the brave and true might be OK, if you can handle how "twee" it can be sometimes |
| 12:10 | Legendary_Linux | Twee? |
| 12:10 | justin_smith | Legendary_Linux: kinda cute, silly |
| 12:11 | blkcat | i enjoyed clojure for the brave and true |
| 12:11 | Legendary_Linux | How much difference is there between Clojure and ClojureScript? |
| 12:11 | blkcat | but you definitely have to be OK with a great deal of levity :p |
| 12:12 | justin_smith | Legendary_Linux: they both use host interop a lot. Aside from the host interop they are very similar. |
| 12:12 | Legendary_Linux | I can deal with that. Thanks for the suggestions, all. |
| 12:12 | justin_smith | the host interop will be very familiar based on your java / javascript experience |
| 12:12 | justin_smith | though the syntax is different of course |
| 12:19 | dnolen | not sure of ATXers hang out here but https://twitter.com/swannodette/status/623527687932481536 |
| 12:29 | crocket | Is there a build-in function for (map #(update % 1 fn) {:a :b ...})? |
| 12:29 | crocket | It is map-val. |
| 12:35 | gfredericks` | there is no built-in map-vals |
| 12:35 | gfredericks` | the easiest is (into {} (for [[k v] m] [k (f v)])) |
| 12:36 | gfredericks` | prismatic/plumbing has it; I'm sure other util libs do too |
| 12:36 | TimMc | crocket: clojure.algo.generic.functor/fmap |
| 12:37 | gfredericks` | oh dear |
| 12:37 | crocket | TimMc, Is it part of core? |
| 12:37 | TimMc | nope |
| 12:37 | TimMc | No lie, we have pulled in that entire lib just for fmap on maps. It's kind of silly. |
| 12:37 | crocket | I have (into {} (map #(update % 1 name) m)) |
| 12:37 | TimMc | [org.clojure/algo.generic "0.1.2"] |
| 12:38 | gfredericks` | TimMc: that's kind of silly |
| 12:38 | TimMc | crocket: (zipmap (keys m) (map f (vals m))) |
| 12:38 | TimMc | there are so many ways to write this |
| 12:39 | crocket | So many ways to confuse users |
| 12:39 | TimMc | fmap is written (into (empty m) (for [[k v] m] [k (f v)])) |
| 12:39 | TimMc | but maybe for perf it should use transients? |
| 12:48 | justin_smith | TimMc: I thought into used transients |
| 12:48 | justin_smith | oh wait no it uses transducers, my bad |
| 12:48 | crocket | transducers win over transients |
| 12:49 | justin_smith | but trans* beats everything |
| 12:49 | crocket | Oh my god, iterate creates a recursive data structure!!! |
| 12:50 | justin_smith | um, it can |
| 12:50 | justin_smith | it doesn't have to |
| 12:50 | justin_smith | ,(iterate inc 0) |
| 12:50 | clojurebot | (0 1 2 3 4 ...) |
| 12:50 | blkcat | they were clearly overwhelmed by this revelation |
| 12:50 | justin_smith | nothing recursive about that data structure |
| 13:08 | xemdetia | and then they died |
| 13:11 | scriptor | wonder what they meant by recursive data structure |
| 13:35 | mmeix | short question: |
| 13:35 | mmeix | I have in a let: |
| 13:36 | mmeix | (let [sw1 (if (< s e) 1 0), sw2 (if (= 1 sw1) 0 1)]) |
| 13:36 | mmeix | there must be a more elegeant way to say this |
| 13:37 | gfredericks` | sw2 (- 1 sw1) |
| 13:38 | mmeix | ah, silly me ... thanks! |
| 13:39 | mmeix | (inc gfredericks) |
| 13:39 | lazybot | ⇒ 142 |
| 13:44 | gfredericks` | mmeix: there's also (bit-xor 1 sw1) |
| 13:44 | mmeix | wow |
| 13:44 | mmeix | ok ... |
| 13:45 | mmeix | would be much faster, I guess ... |
| 13:45 | gfredericks` | hypothetically |
| 13:45 | justin_smith | ,(bit-xor 1 1) |
| 13:45 | clojurebot | 0 |
| 13:45 | justin_smith | ,(bit-xor 1 0) |
| 13:45 | clojurebot | 1 |
| 13:45 | TimMc | blkcat: "My god, it's full of cons cells!" |
| 13:45 | mmeix | the wise are thinking alike :-) |
| 13:47 | mmeix | aha, this is a function of clojure.lang.Numbers in source, interesting |
| 13:47 | scriptor | not sure if bit-xor would be that much faster |
| 13:48 | mmeix | (in my case speed doesn't matter much) |
| 13:49 | mmeix | (just flipping a flag in a SVG path) |
| 13:49 | gfredericks` | yeah do whatever is the clearest to you |
| 14:01 | gfredericks` | omg I think I have to implement bit-count for 64-bit integers in cljs |
| 14:01 | justin_smith | gfredericks`: how do you even do a 64 bit integer in cljs? where do you get the extra bits to make that work? |
| 14:04 | gfredericks` | justin_smith: gclosure has a Long |
| 14:04 | TimMc | justin_smith: Store them as properties on the number. |
| 14:04 | gfredericks` | lol |
| 14:05 | TimMc | (function(x) { x.foo = "bar"; console.log(x.foo); })(3) |
| 14:05 | TimMc | ^ Prints undefined, but does not error. |
| 14:05 | gfredericks` | erroring would be hostile to developers |
| 14:05 | gfredericks` | nobody likes to see error messages |
| 14:08 | TimMc | I think 3 is getting boxed as a Number, but I don't know why Number silently throws away property writes. |
| 14:10 | gfredericks` | what does it mean for a js number to be boxed? |
| 14:11 | amalloy | TimMc: (function(x) {console.log(x.foo="bar");})(3) // quick hack TODO figure out why this is needed |
| 14:11 | TimMc | amalloy: :-) |
| 14:12 | TimMc | gfredericks`: new Number(3) + 5 //= 8 |
| 14:12 | TimMc | typeof new Number(3) //= "object" |
| 14:13 | TimMc | typeof Number(3) //= "number" |
| 14:14 | amalloy | TimMc: actuall new Number(3) + 5 == 8 in my browser |
| 14:14 | amalloy | but here is a funny thing i just found in the ecmascript spec: Number is the inverse of new Number |
| 14:24 | justin_smith | amalloy: did you see my hilarious destructuring pitfall the other day? |
| 14:24 | amalloy | uh |
| 14:25 | amalloy | oh, the keyword and some sort of not-actually-space space? |
| 14:25 | justin_smith | ,(let [{:keys {a b c d}} {:a 0 :b 1 :c 2 :d 3}] [a b c d]) |
| 14:25 | clojurebot | [nil nil nil nil] |
| 14:25 | amalloy | hah |
| 14:25 | justin_smith | of course the keys arg should have been a vector |
| 14:25 | justin_smith | but it just silently gives you nil |
| 14:26 | justin_smith | amalloy: led to a hilarious wild goose chase |
| 14:26 | amalloy | ,(let [{:keys #{a b c d}} {:a 1 :b 2 :c 3 :d 4}] [a b c d]) |
| 14:26 | clojurebot | [1 2 3 4] |
| 14:26 | amalloy | ,(let [{:keys #{a b c d e f g h i}} {:a 1 :b 2 :c 3 :d 4}] [a b c d]) |
| 14:26 | clojurebot | [1 2 3 4] |
| 14:26 | amalloy | hmmmph, i was hoping for some sort of rearrangement from the conversion to hashset |
| 14:27 | justin_smith | another fun one (which I found much faster) ##(let [{:keys [a b c :a all]} {:a 0 :b 1 :c 2}] all) |
| 14:27 | lazybot | ⇒ nil |
| 14:27 | justin_smith | of course the :as all needs to be moved out of the vector |
| 14:27 | justin_smith | err, I didn't even do the :as right this time |
| 14:27 | justin_smith | another fun one (which I found much faster) ##(let [{:keys [a b c :as all]} {:a 0 :b 1 :c 2}] all) |
| 14:27 | lazybot | ⇒ nil |
| 14:28 | Bronsa | c.c/destructure is just awful |
| 14:29 | Bronsa | unreadable, unmaintainable and accepts lots of bad inputs |
| 14:29 | amalloy | Bronsa: has anyone tried to rewrite it? it seems like it shouldn't be *that* hard to redo from scratch, even if reading the existing one is impossible |
| 14:29 | Bronsa | amalloy: have fun trying to get a refactoring commit into clojure |
| 14:30 | justin_smith | Bronsa: on top of that, also it can be slow, and it can undermine laziness |
| 14:30 | amalloy | oh, sure |
| 14:30 | justin_smith | those might be harder to fix |
| 14:30 | amalloy | justin_smith: you mean because of the nth calls? |
| 14:30 | justin_smith | amalloy: I think so, it's actually something that came to my attention via yourself. I just superstitiously avoid destructuring when I need maximal laziness now :P |
| 14:31 | Bronsa | amalloy: I think the big issue with the current version is that it tries too hard to be super generic and reuse one code-path to do all the nested destructuring |
| 14:31 | amalloy | oh, i meant the slowness. that's not what causes laziness issues |
| 14:31 | Bronsa | justin_smith: it can also mess with locals clearing! |
| 14:31 | justin_smith | ahh, I just know that from benchmarking. Probably the extra collection making and such? not sure |
| 14:31 | justin_smith | wow |
| 14:31 | Bronsa | (because of a bug in locals clearing though) |
| 14:32 | TimMc | amalloy: //= was supposed to be a comment followed by an equals sign, like ;;= |
| 14:32 | Bronsa | justin_smith: it will sometimes bind unused and unreachable locals which the compiler can't clear. I have a ticket w/ patch in jira but.. |
| 14:32 | amalloy | justin_smith: well because it calls nth a lot |
| 14:33 | amalloy | ,(#'clojure.core/destructure '[_ _ _ _ _ _ _ _ _ _ x]) |
| 14:33 | clojurebot | [_ _ _ _ _ ...] |
| 14:33 | amalloy | ,(#'clojure.core/destructure '[[_ _ _ _ _ _ _ _ _ _ x] y]) |
| 14:33 | clojurebot | [vec__128 y _ (clojure.core/nth vec__128 0 nil) _ ...] |
| 14:33 | justin_smith | ahh |
| 14:33 | amalloy | so if y is a seq it calls nth 0, nth 1, nth 2... |
| 14:33 | justin_smith | nice |
| 14:33 | amalloy | where instead it could be using nthnext and first |
| 14:35 | Bronsa | amalloy: uh, are you saying walking a seq of a vector is faster than accessing each element? |
| 14:36 | amalloy | Bronsa: for a vector it's not, and for a seq itis |
| 14:36 | TimMc | &(let [{:keys {AAAAA BBBBB}} {(keyword "[AAAAA BBBBB]") [5 6]}] AAAAA) ;; amalloy, another result from justin_smith's discovery |
| 14:36 | lazybot | ⇒ 5 |
| 14:36 | kwladyka_ | How to transform (1 2 3 4) into (4 1 2 3)? |
| 14:36 | kwladyka_ | in elegant way |
| 14:36 | Bronsa | amalloy: right, I guess vector destructuring is optimized for vector access |
| 14:36 | TimMc | kwladyka_: (constantly (list 4 1 2 3)) |
| 14:36 | amalloy | right, but an awful lot of the time we actually have lists |
| 14:37 | hiredman | no, it is sequential destructuring |
| 14:37 | Bronsa | ah |
| 14:37 | amalloy | and it's not hard to check whether the thing you're destructuring supports nth via whatever interface |
| 14:37 | Bronsa | yeah, true that |
| 14:37 | kwladyka_ | TimMc, ? |
| 14:37 | amalloy | or to make nthnext and first be fast on vectors (like subvec) |
| 14:37 | TimMc | kwladyka_: (cons (last xs) (butlast xs)) perhaps |
| 14:37 | TimMc | kwladyka_: You didn't explain the relationship between the two, so I had to guess. |
| 14:38 | TimMc | Maybe you want all inputs to become (4 1 2 3), for example! |
| 14:38 | amalloy | TimMc: that was the one i guessed when he asked me |
| 14:38 | kwladyka_ | TimMc, you have strange intuition :) |
| 14:38 | kwladyka_ | TimMc, anyway thx for solution |
| 14:38 | amalloy | although since i wasn't reading it at the time i mis-guessed the cause |
| 14:38 | chouser | (->> xs cycle (drop 3) (take 4)) |
| 14:39 | TimMc | kwladyka_: Did I guess right, then? |
| 14:39 | kwladyka_ | TimMc, (cons (last xs) (butlast xs)) |
| 14:40 | chouser | kwladyka_: depending on the other operations you intend to do, a persistent queue might work well |
| 14:41 | kwladyka_ | chouser, can you give me an example? |
| 14:43 | chouser | a persistent queue is fast for conj'ing on one end and peek/pop'ing from the other, so you could efficiently take an item (4) from one end and put it back on the other end. |
| 14:44 | chouser | if you do that a lot, or on a large collection, it might be more efficient than a vector or list which has to be rebuilt every time you do that "rotate" operation you asked about |
| 14:44 | chouser | on the other hand, it may then be hard to access the full contents of the collection in the order you want for whatever else you're doing with it. |
| 14:45 | kwladyka_ | chouser, are you talking about http://clojuredocs.org/clojure.core/persistent! ? |
| 14:45 | chouser | nope. |
| 14:46 | chouser | ,(-> clojure.lang.PersistentQueue/EMPTY (into [1 2 3 4])) |
| 14:46 | clojurebot | #object[clojure.lang.PersistentQueue 0x22125a58 "clojure.lang.PersistentQueue@e93c3"] |
| 14:47 | kwladyka | oh... thx |
| 14:47 | chouser | ,(let [q (into clojure.lang.PersistentQueue/EMPTY [1 2 3 4])] (-> q (conj (peek q)) pop seq)) |
| 14:47 | clojurebot | (2 3 4 1) |
| 14:48 | gfredericks` | conj-peek-pop-seq would be a good name for *something* |
| 14:48 | kwladyka | generally i need do from (1 2 3 4 2 3 53 23 932 2) all possible configurations |
| 14:48 | chouser | ,(let [q (into clojure.lang.PersistentQueue/EMPTY (reverse [1 2 3 4]))] (-> q (conj (peek q)) pop reverse)) |
| 14:48 | clojurebot | (4 1 2 3) |
| 14:48 | kwladyka | *all possible unique configurations |
| 14:49 | chouser | so, those 'reverse' operations are relatively expensive, but if you can do the things you need to in-between them, or figure out how to never need them, you'd be winning. |
| 14:50 | amalloy | "all possible configurations?" |
| 14:50 | amalloy | you are looking for the function named permutations, or what? |
| 14:51 | kwladyka | amalloy, i have chess pieces and i have to try them in all possible unique configurations from first to the last one |
| 14:51 | amalloy | what is a unique configuration? |
| 14:52 | amalloy | this is getting back to TimMc's answer |
| 14:52 | kwladyka | so (:king :king :queen) (:king :queen :king) (:queen :king :king:) <- this is easy one. |
| 14:52 | gfredericks` | sounds like permutations |
| 14:52 | kwladyka | as you can see :king is 2 times there |
| 14:53 | kwladyka | but i am not doing (:king :queen :king) twice because it doesn't make sense |
| 14:53 | kwladyka | gfredericks`, but there is no function like permutation in Clojure as i seee |
| 14:55 | kwladyka | hmm but maybe http://clojure.github.io/math.combinatorics/#clojure.math.combinatorics/permutations |
| 14:56 | gfredericks` | ,(defn unique-permutations [xs] (let [m (frequencies xs)] ((fn self [m] (if (empty? m) [[]] (mapcat (fn [[x n]] (map #(cons x %) (self (if (= 1 n) (dissoc m x) (update m x dec))))) m)))))) |
| 14:56 | clojurebot | #'sandbox/unique-permutations |
| 14:56 | gfredericks` | ,(unique-permutations [:king :king :queen]) |
| 14:56 | clojurebot | #error {\n :cause "Unable to resolve symbol: unique-permutations in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: unique-permutations in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to r... |
| 14:56 | gfredericks` | what |
| 14:56 | gfredericks` | ,sandbox/unique-permutations |
| 14:56 | clojurebot | #error {\n :cause "No such var: sandbox/unique-permutations"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such var: sandbox/unique-permutations, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "No such var: sandbox/unique-permutations"\n :at [cl... |
| 14:56 | gfredericks` | ,(defn unique-permutations [xs] (let [m (frequencies xs)] ((fn self [m] (if (empty? m) [[]] (mapcat (fn [[x n]] (map #(cons x %) (self (if (= 1 n) (dissoc m x) (update m x dec))))) m)))))) |
| 14:56 | clojurebot | #'sandbox/unique-permutations |
| 14:56 | gfredericks` | ,(unique-permutations [:king :king :queen]) |
| 14:56 | clojurebot | #error {\n :cause "Wrong number of args (0) passed to: sandbox/unique-permutations/self--71"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: sandbox/unique-permutations/self--71"\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" 28]\n [sandbox$unique_... |
| 14:57 | kwladyka | gfredericks`, i guess clojurebot doesn't remember function from query before |
| 14:57 | gfredericks` | ,(defn unique-permutations [xs] (let [m (frequencies xs)] ((fn self [m] (if (empty? m) [[]] (mapcat (fn [[x n]] (map #(cons x %) (self (if (= 1 n) (dissoc m x) (update m x dec))))) m))) m))) |
| 14:57 | clojurebot | #'sandbox/unique-permutations |
| 14:57 | gfredericks` | ,(unique-permutations [:king :king :queen]) |
| 14:57 | clojurebot | ((:king :king :queen) (:king :queen :king) (:queen :king :king)) |
| 14:57 | gfredericks` | hey yay |
| 14:57 | gfredericks` | only two tries |
| 14:57 | gfredericks` | ,(unique-permutations [:king :rook :queen]) |
| 14:57 | clojurebot | ((:king :rook :queen) (:king :queen :rook) (:rook :king :queen) (:rook :queen :king) (:queen :king :rook) ...) |
| 14:57 | gfredericks` | ,(unique-permutations [:king :king]) |
| 14:57 | clojurebot | ((:king :king)) |
| 14:58 | amalloy | that's a cute way to handle duplicates, gfredericks` |
| 14:58 | gfredericks` | amalloy: thanks! |
| 14:58 | kwladyka | gfredericks`, respect |
| 14:58 | gfredericks` | I like to think of frequencies as returning a multiset |
| 15:07 | TimMc | clojurebot: I like to think |of| frequencies |
| 15:07 | clojurebot | 'Sea, mhuise. |
| 15:09 | snowell | Just when I think I understand these bots... |
| 15:11 | rhg135 | Heh |
| 15:14 | kwladyka | damn... i killed intellij using permutation in REPL |
| 15:18 | gfredericks` | hey snapchat I just successfully ported the immutable RNG to cljs |
| 15:18 | gfredericks` | it gives identical results |
| 15:19 | dnolen | gfredericks`: cool did you end up using goog.math.Long for this? |
| 15:19 | gfredericks` | dnolen: oh absolutely |
| 15:19 | dnolen | gfredericks`: cool! |
| 15:19 | gfredericks` | dnolen: I had to write bit-count myself but everything else was there |
| 15:19 | dnolen | gfredericks`: excellent |
| 15:19 | gfredericks` | dnolen: next comes the part where I find out it's unsalvageably slow |
| 15:20 | dnolen | gfredericks`: haha, I suspect it will be OK, I think test.check would dominate not goog.math.Long ops |
| 15:20 | gfredericks` | I hope so |
| 15:20 | dnolen | gfredericks`: last I checked it as something like 4X perf hit over regular arithmetic |
| 15:21 | dnolen | and the biggest time sink in test.check is GC |
| 15:21 | kwladyka | oh god... it produce so many results from so small collection |
| 15:21 | gfredericks` | dnolen: makes me want to rewrite the generators with transducers |
| 15:21 | gfredericks` | kwladyka: the maybe good news is that it's lazy |
| 15:21 | dnolen | gfredericks`: def |
| 15:22 | justin_smith | ,(defn get-name [] (->> 'clojure.core ns-publics keys shuffle (take 3) (clojure.string/join \-) symbol)) |
| 15:22 | clojurebot | #'sandbox/get-name |
| 15:22 | justin_smith | ,(repeatedly get-name) ; gfredericks` |
| 15:22 | clojurebot | (spit-nnext-*command-line-args* char?-subs-dissoc! comment-completing-read-string apply-keys-int print-method-case-drop ...) |
| 15:23 | gfredericks` | (inc justin_smith) |
| 15:23 | lazybot | ⇒ 279 |
| 15:23 | kwladyka | gfredericks`, yes but i am scare of time needed to run whole algorithm from start to the end |
| 15:24 | gfredericks` | kwladyka: yeah combinatorial stuff can be tricky that way |
| 15:24 | kwladyka | which each permutation i need check all possible configuration on chess |
| 15:24 | kwladyka | *with |
| 15:25 | gfredericks` | kwladyka: is it a permutation of 8 pieces? |
| 15:25 | kwladyka | hmm but as i see 99% of time it was time to show me text on screen not counting |
| 15:25 | gfredericks` | ,(defn unique-permutations [xs] (let [m (frequencies xs)] ((fn self [m] (if (empty? m) [[]] (mapcat (fn [[x n]] (map #(cons x %) (self (if (= 1 n) (dissoc m x) (update m x dec))))) m))) m))) |
| 15:25 | clojurebot | #'sandbox/unique-permutations |
| 15:25 | gfredericks` | ,(count (unique-permutations '(R N B K Q B N R))) |
| 15:25 | clojurebot | 5040 |
| 15:25 | kwladyka | gfredericks`, no... as many as user want on board size as user want |
| 15:25 | justin_smith | ,defn get-name [] (->> 'clojure.core ns-publics keys (mapcat (fn [s] (clojure.string/split (name s) #"-"))) shuffle (take 3) (clojure.string/join \-) symbol)) |
| 15:25 | clojurebot | #error {\n :cause "Can't take value of a macro: #'clojure.core/defn"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/defn, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Can't take value of a macro: #'clojur... |
| 15:25 | justin_smith | ,(defn get-name [] (->> 'clojure.core ns-publics keys (mapcat (fn [s] (clojure.string/split (name s) #"-"))) shuffle (take 3) (clojure.string/join \-) symbol)) |
| 15:25 | clojurebot | #'sandbox/get-name |
| 15:26 | justin_smith | ,(repeatedly get-name) |
| 15:26 | clojurebot | (update-count-seq *1-min-ctor condp-with-*print byte-chars-history boolean-vector-vary ...) |
| 15:26 | kwladyka | anyway... i have to finish algorithm and we will see how long it will take |
| 15:26 | kwladyka | there is no other way :) |
| 15:34 | TimMc | (inc justin_smith) |
| 15:34 | lazybot | ⇒ 280 |
| 15:35 | TimMc | ,(meta #'completing) |
| 15:35 | clojurebot | {:arglists ([f] [f cf]), :doc "Takes a reducing function f of 2 args and returns a fn suitable for\n transduce by adding an arity-1 signature that calls cf (default -\n identity) on the result argument.", :added "1.7", :line 6560, :column 1, ...} |
| 15:35 | gfredericks` | heck yeah it generates identical doubles as well |
| 15:35 | TimMc | that's great! |
| 16:39 | riogr | In my program, I have the state in a variable I call `current-buffer`. It has an atom, that is swap!-ed and reset!-ed at certain times. Should you in clojure *earmuff* such variables? They never change (always point to the atom) but the value from deref-ing the atom _is_ changing. To *earmuff* or not to earmuff? |
| 16:42 | justin_smith | riogr: in clojure earmuffs are for dynamic bindings, not atoms |
| 16:43 | riogr | I see. Thank you justin_smith for clearing it up! Back to the hacking... |
| 16:43 | justin_smith | riogr: there's even a message about it |
| 16:43 | justin_smith | ,(def *foo* (atom nil)) |
| 16:43 | clojurebot | #error {\n :cause "denied"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6740]}\n {:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojureb... |
| 16:43 | riogr | justin_smith: saw that, but didn't really understand.. |
| 16:43 | justin_smith | err... that's not the usual message |
| 16:44 | justin_smith | riogr: OK. there's a good section on dynamic bindings on clojure.org where vars are documented |
| 17:12 | DocSolver | Hi all! I'm trying to teach myself clojure with a book and the REPL and I have two questions: |
| 17:13 | DocSolver | My first question: when I start a REPL outside a project I get an outdated Clojure version (1.6.0), even though I made a project.clj in the ~/.lein folder with a dependency on 1.7.0. Am I doing something wrong? |
| 17:14 | DocSolver | ('m on MacOSX) |
| 17:17 | justin_smith | DocSolver: lein doesn't use a project.clj from .lein |
| 17:18 | justin_smith | DocSolver: you'll need to wait for a newer lein version before non-project repls use the brand new clojure version (it's only been official for a few weeks at most) |
| 17:18 | DocSolver | ok, then I must have misread that somewhere. |
| 17:18 | DocSolver | thank you for the clarification! |
| 17:18 | justin_smith | np |
| 17:19 | justin_smith | DocSolver: in practice it's not so hard to just use projects |
| 17:19 | justin_smith | since they are so easy to generate |
| 17:19 | DocSolver | k, will do |
| 17:20 | DocSolver | also, another thing I was wondering is about the syntax: it is mostly quite clear but I am confused by the cases where a keyword has a specific meaning. For example the :keys speical keyword to destructure a hashmap. Why is this a keyword and not a function? |
| 17:20 | justin_smith | I have a "just experimenting" project that pulls in clojure 1.7 plus some of my favorite libs like core.async (which I use often, but not ubiquitously to put in my profiles.clj) |
| 17:20 | justin_smith | DocSolver: because that keyword is handled specially by that reader - you can think of it like command line args on a *nix system |
| 17:21 | justin_smith | DocSolver: the function is clojure.core/destructure |
| 17:21 | justin_smith | and it uses things like :keys and :as to guide its execution |
| 17:21 | DocSolver | does that mean that these keywords are reserved? Or only in that specific context? |
| 17:21 | justin_smith | there's a macro that grabs that binding vector, then feeds it to destructure, then uses the result |
| 17:22 | justin_smith | no, they are not reserved, they just have a special meaning in that context, similar to command line switches |
| 17:22 | justin_smith | DocSolver: really it's not much different than how a vector is used by defn / fn |
| 17:23 | justin_smith | it's not that the vector is special, it's that fn / defn treat a vector in that position in a special manner |
| 17:23 | DocSolver | but it does matter that the keyword is named :keys right? |
| 17:23 | justin_smith | DocSolver: sure, other keywords mean other things in that context |
| 17:23 | justin_smith | DocSolver: like :strs |
| 17:24 | DocSolver | I haven't stumbled upon that one in the book I'm reading yet... but I will keep it in mind |
| 17:24 | DocSolver | Thanks for the clarifications Justin, really appreciate! |
| 17:24 | justin_smith | DocSolver: yeah, :strs is practically secret, it gets used so rarely :) |
| 17:24 | justin_smith | np |
| 17:25 | justin_smith | ,(let [{:strs [a]} {"a" 41}] (inc a)) |
| 17:25 | clojurebot | 42 |
| 17:27 | DocSolver | justin_smith: so what is the added value of using :strs ? |
| 17:27 | justin_smith | DocSolver: same as for keys, avoids repetition when destructuring |
| 17:28 | justin_smith | DocSolver: often a hash-map coming from a database or an http API will come back with strings as keys rather than keywords |
| 17:29 | justin_smith | what most people do is do a tree-walk converting the strings to keywords (or at least walking and converting the top level, or converting while parsing with a json parser). Really you can just use the strings. |
| 17:30 | DocSolver | You managed to confuse me a bit with the :str :-) I don't really see the difference with :keys. I assume it's not an alias? |
| 17:30 | justin_smith | DocSolver: :keys works with keywords, :strs works with strings |
| 17:31 | justin_smith | these are different datatypes, they are not equivalent when used as hash-map keys |
| 17:31 | justin_smith | ,(get {"a" 0} :a) |
| 17:31 | clojurebot | nil |
| 17:31 | justin_smith | ,(get {"a" 0} "a") |
| 17:31 | clojurebot | 0 |
| 17:31 | DocSolver | The example about :keys in the book I'm reading is: |
| 17:31 | DocSolver | ,(let [{:keys [flower1 flower2]} {:flower1 "red" :flower2 "blue"}] (str "The flowers are " flower1 " and " flower2)) |
| 17:31 | clojurebot | "The flowers are red and blue" |
| 17:32 | DocSolver | It obviously doesnt work if I replace :keys with :strs but your example seems really similar |
| 17:32 | justin_smith | DocSolver: I bet you could translate that to use :strs, by changing the keys in the map |
| 17:32 | DocSolver | Is it because you're extracting only one key? |
| 17:32 | justin_smith | DocSolver: it is because :a is not equal to "a" |
| 17:32 | justin_smith | they are different data types |
| 17:32 | DocSolver | Aaaah, now I see: your key is a string |
| 17:32 | justin_smith | :a is not a special syntax for map keys, it is a type of data |
| 17:33 | DocSolver | Okay, it's good that you point that out because I practically only see :keys being used as... erm... keys in objects |
| 17:33 | justin_smith | DocSolver: objects != hash-maps |
| 17:33 | justin_smith | hash-maps are one class of objects |
| 17:34 | justin_smith | but we have Objects via the jvm too, entirely different beast usually... |
| 17:34 | justin_smith | DocSolver: but stick to hash-maps now, and use them as you would usually use objects, and you can sort out the rest when you are more experienced |
| 17:35 | DocSolver | Okay; I did mean hash maps but I'm still too much in Javascript lingo... |
| 17:36 | DocSolver | Actually the :keywords system in Clojure kind of reminds me of symbols in the new Ecmascript 6 which are provided as a means to avoid collisions that might occur with string keys. Or is this not a good comparison? |
| 17:36 | justin_smith | DocSolver: heh, if you ever use cljs, you can use js Objects and cljs hash-maps (which are a kind of js object...) |
| 17:36 | justin_smith | DocSolver: well, keywords can be namespaced, and we use the namespacing to avoid collisions |
| 17:37 | DocSolver | but what is the added value of keywords, as opposed to using strings instead? |
| 17:37 | justin_smith | but we also use keywords in literal source code because it helps differentiate a string used as a data type representing human readable text, as opposed to keys in a map or other usage of tokens |
| 17:37 | justin_smith | also keywords can be called like functions, they look up a value in a hash-map |
| 17:38 | justin_smith | ,(:foo {:foo 0}) |
| 17:38 | clojurebot | 0 |
| 17:39 | DocSolver | okay, that's clear. |
| 17:40 | DocSolver | So it's actually other languages which use strings for both purposes and clojure separates these uses by creating a separate data type... |
| 17:41 | justin_smith | DocSolver: right. I saw a comical version of this the other day from a haskell user on twitter: "should the type be string? I dunno, would the complete works of shakespeare translated to mandarin be a valid value?" |
| 17:42 | DocSolver | :two_households_both_alike_in_dignity_In_fair_Verona_... no that doesn't feel right :-) |
| 17:42 | justin_smith | haha |
| 17:43 | DocSolver | actually, the fact that a leyword can't contain spaces is a clear indicator of what you wrotr |
| 17:43 | justin_smith | DocSolver: right. Well a literal can't. As you learn more clojure you find out all kinds of evil terrible bad things you shouldn't do that are actually quite easy. |
| 17:44 | DocSolver | I don't wanna know :-) |
| 17:45 | DocSolver | Alright Justin, you helped me a lot. Now I'm returning to the book and the REPL :-) This was a nice first experience with the Clojure community! |
| 17:45 | justin_smith | ,(keyword "OK I won't tell you how.") |
| 17:45 | clojurebot | :OK I won't tell you how. |
| 17:46 | justin_smith | DocSolver: awesome, thanks |
| 17:47 | DocSolver | ,(keyword "Two households, both alike in dignity, In fair Verona, where we lay our scene, From ancient grudge break to new mutiny, Where civil blood makes civil hands unclean. From forth the fatal loins of these two foes A pair of star-cross'd lovers take their life; Whose misadventured piteous overthrows Do with their death bury their parents' strife. The fearful passage of their death-mark'd love, And the continuance of their p |
| 17:47 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading string> |
| 17:47 | DocSolver | even romeo and julia doesnt fit... |
| 17:48 | justin_smith | it's an irc limitation, lol |
| 18:05 | sdegutis | Help. |
| 18:06 | sdegutis | This works from `lein run`, but not from inside a jar: (->> (resource "public/assets") (file) (file-seq)) |
| 18:06 | sdegutis | It complains with an illegal argument exception saying "not a file". |
| 18:07 | sdegutis | So in Clojure, whether in a .jar or not, how do you get a list of files in a directory within your ./resources/ dir? |
| 18:10 | justin_smith | sdegutis: things inside jars are not files |
| 18:10 | justin_smith | sdegutis: if you want to access things inside jars, don't use file, use resource |
| 18:10 | justin_smith | sdegutis: jars do not contain directories |
| 18:11 | sdegutis | Okay. |
| 18:11 | sdegutis | So then, in Clojure, whether in a .jar or not, how do you get a list of "files" in a "directory" within your ./resources/ dir? |
| 18:13 | justin_smith | well, "resources" itself won't be in the jar |
| 18:14 | Cr8 | there's not really a good way to do it it -- (resource) will pull a file out of any jar on the classpath |
| 18:14 | justin_smith | best you can do is list things under some relative path on the classpath |
| 18:14 | Cr8 | so you have to use the ZIP apis to check every jar on the classpath |
| 18:14 | justin_smith | answer to that, I am working on |
| 18:14 | hiredman | there is a large assumption there |
| 18:14 | hiredman | that things can only come out of jars on the classpath |
| 18:15 | Cr8 | also dirs on classpath |
| 18:15 | hiredman | resource, and resources actually load things from classloaders |
| 18:15 | hiredman | which can, for example, magic up stuff out of no where, or load things from random urls, etc |
| 18:15 | Cr8 | yeah, could have a magic classloader that you can't actually ask for a list |
| 18:15 | Cr8 | like some http server you dont control -- you cant necessarily get a listing |
| 18:17 | amalloy | justin_smith, Bronsa: in case anyone is interested i wrote up a version of destructure that isn't just one giant function, and uses first/next on vectors instead of nth: https://www.refheap.com/de3767810a33dd855f0bc803e |
| 18:17 | sdegutis | Thanks. I'll do this outside Closure. |
| 18:17 | justin_smith | amalloy: cool |
| 18:17 | sdegutis | Appreciated much. |
| 18:18 | amalloy | doesn't have all the error handling but i think it has all the features |
| 18:44 | justin_smith | just found an apt quote from a 20th century music composer: "now that things are simple, there's so much to do" |
| 18:44 | justin_smith | (Morton Feldman) |
| 21:47 | slaterr | map returns a lazy sequence. what does a lazy sequence mean exactly? is it like iterators in C++? or sequence in python |
| 21:49 | amalloy | it is a thing you can get an iterator on. but it stays valid when you do, and future calls cache the already-computed values. it's not like an iterator that gets mutated as you request elements from it and can only use once |
| 21:49 | slaterr | yeah I see |
| 21:50 | slaterr | what if I only iterate it once? how much memory will it use |
| 21:52 | celwell | Hello, does anything like this already exist? (defmacro unless [pred x y] `(if (not (~pred ~x)) ~x ~y)) |
| 21:52 | celwell | Ex. usage: (unless Double/isNaN (Double. "0.75") 0) |
| 21:52 | celwell | Or, is there a better pattern? |
| 21:53 | amalloy | celwell: why would that be better than using when-not? |
| 21:53 | amalloy | oh, you're not returning nil, but rather y |
| 21:54 | celwell | Yeah, it's an if but i don't want to rewrite 'x' |
| 21:55 | celwell | My name unless is kind of misnomer |
| 21:56 | amalloy | i don't think there's anything very good built-in. with flatland/useful you could write (-> x (fix pred y)) |
| 21:56 | slaterr | or, to repharse, if I iterate through a lazy sequence with a million elements only once will they all be stored in memory or will it just use memory required to store a single element? |
| 21:56 | amalloy | slaterr: i mean the GC is nondeterministic so it could run whenever, but when the GC *does* run, only one element wll be kept |
| 21:58 | celwell | amalloy: huh... seems like it would be a common pattern for data validation w/ defaults |
| 21:58 | slaterr | i thought maybe clojure compiler is smart enough to notice that it does not need to cache all those results, since they are not used again |
| 21:59 | amalloy | actually maybe cond-> does that now. i don't remember how that works |
| 21:59 | amalloy | ,(doc cond->) |
| 21:59 | clojurebot | "([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression." |
| 21:59 | amalloy | ,(cond-> 2 even? inc) |
| 21:59 | clojurebot | 3 |
| 21:59 | amalloy | ,(cond-> 2 odd? inc) |
| 21:59 | clojurebot | 3 |
| 22:00 | amalloy | right, thought so. it wants a bool, not a predicate, so it doesn't help you avoid repeating x |
| 22:03 | celwell | Thanks a cool function though, might be useful for other things. Thanks |
| 22:39 | namra | hm is there no way to ask leiningen for verbose output |
| 22:39 | namra | cause it's kinda frustrating when compilling something and it just hangs somewhere |
| 22:39 | namra | without ever finishing |
| 22:46 | justin_smith | namra: that's caused by top level side effects |
| 22:47 | justin_smith | namra: all your namespaces get run at the top level when compiling, the only way to make it not hang is to have no side effects at the top level of the file |
| 22:47 | justin_smith | anything that "does anything" should be in functions called by your -main |
| 22:48 | justin_smith | namra: you can use jstack (it's a command line tool that comes with the jdk) to see where the clojure process is hanging |
| 22:49 | namra | justin_smith: thanks |
| 22:50 | namra | currently i solved it by removing :aot :all from the uberjar profile |
| 22:50 | namra | but like to know why it doesn't work on the new dev machine cause on the old one the compiliation works |
| 22:50 | justin_smith | oh, that's interesting |
| 22:51 | justin_smith | in my experience a hanging compile is almost always some small thing I didn't notice, like launching a core.async go block in a def |
| 22:52 | justin_smith | (which means the core.async threads spin up, which means the compiling vm does not exit) |
| 22:55 | namra | justin_smith: thanks that was the issue |
| 22:55 | justin_smith | core.async? |
| 22:55 | clojurebot | core.async is 100% imperative |
| 22:57 | namra | had code that connected to a server outside of main |
| 22:57 | justin_smith | ahh |
| 23:27 | namra | ah how i'd like to do more with clojure :/ |
| 23:28 | blkcat | i'm dreadfully tempted to use om for an upcoming work project |
| 23:28 | namra | om? |
| 23:29 | justin_smith | namra: clojurescript library that uses react.js (but actually performs better thanks to immutable data structures last I heard) |
| 23:29 | justin_smith | namra: from the brilliant dnolen |
| 23:29 | justin_smith | ~om |
| 23:29 | clojurebot | Titim gan éirí ort. |
| 23:29 | namra | ah thanks |
| 23:30 | blkcat | it looks absolutely brilliant |
| 23:30 | TEttinger | clojurebot: om is a clojurescript library that uses react.js . Om is so hot right now! |
| 23:30 | clojurebot | Ik begrijp |
| 23:31 | justin_smith | TEttinger: I improved my clojure.core name generator |
| 23:31 | TEttinger | oh? |
| 23:33 | justin_smith | TEttinger: digging it up |
| 23:33 | justin_smith | ,(defn get-name [] (->> 'clojure.core ns-publics keys (mapcat (fn [s] (clojure.string/split (name s) #"-"))) shuffle (take (inc (rand-int 3))) (clojure.string/join \-) symbol)) |
| 23:33 | clojurebot | #'sandbox/get-name |
| 23:34 | justin_smith | (repeatedly get-name) |
| 23:34 | justin_smith | ,(repeatedly get-name) |
| 23:34 | clojurebot | (re send-dorun object-with-drop defmulti-keep-aset >Vec-key-dec' ...) |
| 23:34 | justin_smith | ,(repeatedly get-name) |
| 23:34 | clojurebot | (sig-make class?-run! read->>-memfn var?--inc filter ...) |
| 23:34 | justin_smith | oh wait |
| 23:34 | amalloy | read->>-memfn |
| 23:34 | amalloy | solid name |
| 23:34 | amalloy | var?--inc |
| 23:34 | justin_smith | ,(defn get-name [] (->> 'clojure.core ns-publics keys (mapcat (fn [s] (clojure.string/split (name s) #"-"))) shuffle (take (+ 2 (rand-int 3))) (clojure.string/join \-) symbol)) |
| 23:34 | clojurebot | #'sandbox/get-name |
| 23:34 | justin_smith | ,(repeatedly get-name) |
| 23:34 | clojurebot | (identity-at-defprotocol biginteger-remove eval-min macroexpand-class-coll-complement map?-unreduced-int ...) |
| 23:35 | justin_smith | amalloy: one I just got in my repl here - >Vec-vec->> |
| 23:35 | justin_smith | ,(repeatedly get-name) |
| 23:35 | clojurebot | (pop-ref-next-repeat >=-ctor find-bit-find-method set->-matcher-array proxy-reader ...) |
| 23:36 | amalloy | computer-generated babble is always strangely compelling |
| 23:37 | justin_smith | for me I think it's cathartic because I have spent so much time cramming things made of those tokens into my brain already |
| 23:38 | justin_smith | ,(repeatedly get-name) |
| 23:38 | clojurebot | (error-transient list-set-unsigned-errors deref-groups not-biginteger subtract-re-int-underive ...) |
| 23:39 | amalloy | not-biginteger. a useful function indeed |
| 23:39 | justin_smith | indeed, should be a predicate, of course |
| 23:40 | justin_smith | ,(repeatedly get-name) |
| 23:40 | clojurebot | (unchecked-in-set-send type-min-in fn*-filterv string-create->map-not satisfies?-shift-aset-with ...) |
| 23:41 | tmtwd | is there something like hiccup for css? |
| 23:42 | justin_smith | tmtwd: garden |
| 23:42 | tmtwd | justin_smith, is it often used by clojure developers? |
| 23:42 | justin_smith | tmtwd: the only reason I haven't used it is designers would rather just use regular css, or maybe sass/less |
| 23:43 | amalloy | that's true of hiccup too |
| 23:44 | justin_smith | amalloy: yeah, we have an unusual division of labor now, which lets us use reagent stuff which is basically hiccup syntax, but before we had to use a more conventional templating engine |