2015-03-03
| 00:00 | h_ | how might I serialize a function such that I could write it to a file and recall an identical function from that file at a later time? |
| 00:00 | puredanger | https://github.com/technomancy/serializable-fn |
| 00:01 | h_ | hooray! thank you friend |
| 00:04 | puredanger | enjoy! |
| 00:08 | h_ | `3`3 |
| 00:08 | h_ | <3<3 even! |
| 02:36 | je | is there a way from the repl to "inspect" data to explore all the interfaces it implements and all the classes it inherits from |
| 02:36 | amalloy | &(ancestors clojure.lang.PersistentVector) |
| 02:36 | lazybot | ⇒ #{clojure.lang.IMeta java.lang.Comparable clojure.lang.Indexed clojure.lang.IPersistentVector java.lang.Iterable java.util.List clojure.lang.Associative clojure.lang.IObj clojure.lang.APersistentVector clojure.lang.Reversible java.lang.Object clojure.lang.Seqable clo... https://www.refheap.com/98040 |
| 02:37 | je | I want to identify commonality for dispaching in a multimethod |
| 02:38 | je | amalloy: nice thanks |
| 02:42 | TEttinger | (inc amalloy) |
| 02:42 | lazybot | ⇒ 231 |
| 03:34 | dm3 | hello |
| 03:34 | daniel` | hi |
| 03:34 | dm3 | is there an "approved" way to detect if a sequence is lazy? |
| 03:35 | dm3 | I know there's a clojure.lang.LazySeq, but does it cover all cases? |
| 04:15 | justin_smith | dm3: it's the only lazy type in clojure. Though they can hide. |
| 04:15 | justin_smith | ,(type (cons :a (range))) |
| 04:15 | clojurebot | clojure.lang.Cons |
| 04:15 | justin_smith | that's a cons, but it's tail is lazy |
| 04:15 | justin_smith | ,(type (range)) |
| 04:15 | clojurebot | clojure.lang.LazySeq |
| 04:18 | dm3 | I'm trying to enforce stricter semantics for an fn which operates in a dynamic scope |
| 04:18 | dm3 | know that there'll be trouble with nested lazy sequences, but forcing the outer one should cover 95% of use cases |
| 04:18 | godd2 | *opens lein repl* (reduce + (range)) ; oh god what have I done |
| 04:19 | dm3 | guess just checking if it's a sequence and doall'ing would be enough |
| 04:19 | justin_smith | dm3: if you know you won't get (range) or (iterate ...) |
| 04:19 | dm3 | yes |
| 04:20 | justin_smith | you could also do a clojure.walk/postwalk, which will hit every subtree, and try to fully descend every subtree |
| 04:20 | justin_smith | hmmm. maybe just a (dorun (tree-seq ...)) |
| 04:27 | dm3 | justin_smith: thanks |
| 04:29 | justin_smith | ,(tree-seq coll? seq [:a [:b {:c 0 :d 1 :e #{1 2 3}}]]) |
| 04:29 | clojurebot | ([:a [:b {:e #{1 3 2}, :c 0, :d 1}]] :a [:b {:e #{1 3 2}, :c 0, :d 1}] :b {:e #{1 3 2}, :c 0, :d 1} ...) |
| 04:35 | TEttinger | &(tree-seq coll? seq [:a [:b {:c 0 :d 1 :e #{1 2 3}}]]) |
| 04:35 | lazybot | ⇒ ([:a [:b {:e #{1 3 2}, :c 0, :d 1}]] :a [:b {:e #{1 3 2}, :c 0, :d 1}] :b {:e #{1 3 2}, :c 0, :d 1} [:e #{1 3 2}] :e #{1 3 2} 1 3 2 [:c 0] :c 0 [:d 1] :d 1) |
| 04:35 | justin_smith | aint no room for a lazy seq to hide in there |
| 04:35 | TEttinger | I have no idea how tree-seq works |
| 04:36 | justin_smith | TEttinger: it returns every sub tree |
| 04:36 | justin_smith | and every sub-tree of each sub-tree |
| 04:36 | justin_smith | the first arg is the function which tells you if a thing has sub-trees |
| 04:36 | justin_smith | the second arg is the thing that returns the sub-trees, if it has them |
| 05:40 | dysfun | what do i need to do to correctly inflate a ns-qualified symbol in an edn file to a value? let's assume for now that the code is in the classpath |
| 05:43 | dysfun | aha, find-var |
| 05:58 | ggherdov | ,(->> '([1 :a] [2 :c]) (sorted-map-by <)) |
| 05:58 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: ([1 :a] [2 :c])> |
| 05:58 | ggherdov | ,(->> '([1 :a] [2 :c]) (apply (sorted-map-by <))) |
| 05:58 | clojurebot | [2 :c] |
| 05:58 | ggherdov | ,(->> '([1 :a] [2 :c]) flatten (apply (sorted-map-by <))) |
| 05:58 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: PersistentTreeMap> |
| 05:59 | ggherdov | you have a list of keyvals (as vectors), and want to build a sorted-map-by. How do you do? |
| 05:59 | Glenjamin | (doc into) |
| 05:59 | clojurebot | "([to from] [to xform from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined. A transducer may be supplied." |
| 06:00 | TEttinger | ,(into (sorted-map-by <) '([1 :a] [2 :c]) ) |
| 06:00 | clojurebot | {1 :a, 2 :c} |
| 06:00 | ggherdov | thanks TEttinger Glenjamin |
| 06:00 | TEttinger | np |
| 07:35 | razum2um | dnolen: what's the status of cljs support of promise/deliver/deref ? |
| 07:35 | dnolen | razum2um: no support is planned, JS is single-threaded |
| 07:50 | razum2um | dnolen: yes, but what king of abstraction should we use to "fix" callback hell? |
| 07:50 | dnolen | razum2um: core.async |
| 07:50 | razum2um | besides of core.async :) |
| 07:50 | razum2um | say, setTimeout |
| 07:51 | dnolen | razum2um: core.async is the best solution |
| 07:52 | razum2um | dnolen: but there is a lot of promise-solutions as libraries (besides ES6 promisses) - why not to map them and choose one of the polyfill for older browsers? |
| 07:53 | dnolen | razum2um: I don't really have anything else to say on this topic than what I've already said. Sorry. |
| 07:53 | razum2um | dnolen: ok then, thanks :) |
| 07:54 | sveri | razum2um: I guess you are free to create your own abstractions over one of the existing libraries |
| 07:54 | sveri | If you feel the need for them |
| 07:55 | razum2um | sveri: yes, native calls to js/.. work, but I just worder why promise is not implemented |
| 07:57 | sveri | I see :-) |
| 08:03 | dnolen | razum2um: if it wasn't clear earlier, JS promise abstractions are nothing like the Clojure promise abstraction which has blocking semantics for deref. This would imply duplicating core.async but would require whole program transform. |
| 08:04 | dnolen | razum2um: it hasn't been done because the semantics can't be preserved |
| 08:04 | dnolen | without too a big tradeoff |
| 08:27 | piranha | hey all! I'm trying to call Java method with spread arguments (...): http://cr.openjdk.java.net/~sundar/jdk.nashorn.api/8u40/javadoc/jdk/nashorn/api/scripting/NashornScriptEngineFactory.html#getScriptEngine-java.lang.String...- |
| 08:27 | piranha | rs-example.server.render> (.getScriptEngine f "-pcc" "-ot=true") |
| 08:27 | piranha | java.lang.ClassCastException: Cannot cast java.lang.String to [Ljava.lang.String; |
| 08:27 | piranha | and it fails with this ^ |
| 08:27 | piranha | am I doing something wrong? |
| 08:28 | piranha | ah! (into-array String ["a", "b"]) helps |
| 08:46 | sveri | Hi, anyone knows how to properly handle umlaute with transit? transit converts umlaute wrong and makes weird chars of it, see this: http://pastebin.com/7Z8x3C5d |
| 08:47 | Eremox | How do i stop cider from swapping to error-buffer and set it to just print the error message in the repl instead? |
| 08:49 | dnolen | sveri: I don't think transit-clj will handle that for you by default, http://stackoverflow.com/questions/15356716/how-can-i-convert-unicode-string-to-ascii-in-java |
| 08:50 | dnolen | sveri: perhaps worth opening an enhancement issue w/ transit-java |
| 08:51 | sveri | dnolen: thank you, I will do that. Not sure exactly, but this is something I would expect to be handled by the library |
| 08:51 | dnolen | sveri: perhaps, not sure about the perf implications though |
| 08:52 | sveri | dnolen: maybe it can be made optional, however, thank you, I open an issue :-) |
| 09:23 | borkdude | I might be brainnumbed, but is there an easier way to update the val in a map? (update-in {:foo "bar"} [:foo] count) |
| 09:23 | borkdude | of a collection of maps that is |
| 09:23 | borkdude | so (map #(update-in ....)) |
| 09:24 | gfredericks | borkdude: clojure 1.7 has update |
| 09:24 | borkdude | gfredericks yes, I heared. |
| 09:24 | borkdude | gfredericks when is it out? |
| 09:25 | gfredericks | dunno; prismatic/plumbing also has it in the meantime |
| 09:25 | borkdude | k |
| 09:26 | gfredericks | ,(defmacro map-> [& exprs] `(map #(-> % ~@(butlast exprs)) ~(last exprs))) |
| 09:26 | borkdude | https://github.com/clojure/clojure/blob/2e76c57d3b7672ce5eca096ed2059d9a1dd379d0/src/clj/clojure/core.clj#L5909 |
| 09:26 | clojurebot | #'sandbox/map-> |
| 09:27 | gfredericks | ,(->> [{:foo 12} {:foo 13} {:foo 92}] (map-> (* 2) (inc))) |
| 09:27 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Number> |
| 09:27 | gfredericks | whoopsiedoodle |
| 09:27 | gfredericks | ,(->> [{:foo 12} {:foo 13} {:foo 92}] (map-> (update :foo * 2))) |
| 09:27 | clojurebot | ({:foo 24} {:foo 26} {:foo 184}) |
| 09:28 | gfredericks | no idea if map-> is defined in some lib somewhere |
| 09:28 | borkdude | gfredericks thanks ;) |
| 09:29 | gfredericks | np |
| 09:51 | borkdude | gfredericks I found reduce-kv also handy |
| 09:53 | gfredericks | borkdude: for your original question? |
| 09:53 | borkdude | gfredericks yes |
| 09:53 | borkdude | gfredericks it was a little bit different than I asked, but eventually this is what I needed. didn't know about this one yet |
| 09:54 | jcromartie | . |
| 09:56 | gfredericks | , |
| 09:56 | jcromartie | excuse me |
| 09:56 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 09:56 | jcromartie | I was cleaning my keyboard |
| 09:56 | jcromartie | :P |
| 09:56 | jcromartie | ,((( |
| 09:56 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 09:56 | gfredericks | ,()))) |
| 09:56 | clojurebot | () |
| 09:56 | jcromartie | I have a recipe for pain |
| 09:57 | jcromartie | a Clojure app that depends on Ruby gems to be available at runtime |
| 09:57 | jcromartie | I think binstubs may be the answer |
| 09:57 | jcromartie | I dunno |
| 09:58 | jcromartie | it's particularly troublesome with Emacs and Cider launching the REPL process |
| 09:58 | jcromartie | I can't figure that one out |
| 10:01 | loliveira | I would like to run java -jar my_uber.jar —repl and get a repl. Do you know how to do that? |
| 10:03 | jcromartie | what was that cider-related channel? |
| 10:05 | katratxo | loliveira: https://github.com/clojure/tools.nrepl#embedding-nrepl-starting-a-server |
| 10:14 | justin_smith | loliveira: java -cp my_uber.jar clojure.main |
| 10:14 | justin_smith | or that |
| 10:14 | justin_smith | but clojure.main will give you a repl |
| 10:15 | loliveira | katratxo: justin_smith: thank you! |
| 10:15 | loliveira | it worked. =) |
| 10:17 | justin_smith | loliveira: if you prefer the nrepl repl to the clojure one, you can launch the nrepl server from your own app (or even from the clojure repl) as described in katratxo 's link, and then connect to it with "lein repl :connect N" where N is the port number it opens |
| 10:19 | loliveira | justin_smith: I will try the nrepl approach. |
| 10:19 | loliveira | justin_smith: I will put the follow up. |
| 10:23 | justin_smith | loliveira: a trick I often use is to have an optional environment variable, which if set, I turn on an nrepl server from my process |
| 10:23 | loliveira | justin_smith: good idea. |
| 10:23 | justin_smith | but the java -cp ... clojure.main is useful for if I want to just run some code with exactly the setup that would be available on the server |
| 10:24 | justin_smith | not running the app, but just running some code that I think might have failed in production for example |
| 10:25 | justin_smith | (I used this recently to verify that tomcat was making the serving of resources inside the jar with unusual names 404) |
| 10:33 | loliveira | aggred |
| 10:34 | loliveira | justin_smith: I have the same need that you had. |
| 10:36 | justin_smith | loliveira: another trick that I needed in that case, because this was a war file and not a jar file, I needed to also explicitly add the clojure.core to the class path because of how wars are packed up |
| 10:36 | justin_smith | probably not an issue in your case |
| 10:37 | loliveira | i used to deploy wars. |
| 11:21 | timvisher | what's the state of clojure servers at this point? last i heard you really weren't supposed to serve out of embedded jetty in prod using `lein ring server`, but people weren't thrilled with tomcat, some people were using application servers (way heavier than i need), and some people were thrilled with http-kit (which is embedded in the app so you can just `lein run`?) |
| 11:22 | justin_smith | timvisher: I think http-kit and aleph are great options, and using lein to run in prod is a bad idea |
| 11:22 | justin_smith | better to create an uberjar and use java -jar ... or java -cp ... |
| 11:23 | justin_smith | lein is a great dev tool, but it doesn't help you much in production |
| 11:23 | schmir | the boot people advertise using boot in production |
| 11:23 | timvisher | justin_smith: indeed. :) i've heard that over the years but never dove into why. is there a good doc somewhere that expresses that? |
| 11:23 | justin_smith | that's a choice I wouldn't be likely to make, but I know that a lot of people use lein in prod too |
| 11:24 | justin_smith | timvisher: for starters, lein starts up an extra vm you don't need. It also sets jvm options that optimize startup time at the expense of performance (turning down the JIT options) |
| 11:25 | justin_smith | timvisher: but even if it wasn't actively reducing performance, it's functionality I don't need, a program I don't need to install, and an extra place for things to break that can be removed from the prod environment |
| 11:25 | timvisher | justin_smith: all good points |
| 11:25 | michaelr` | anything out there which converts html to clean, formatted hiccup? |
| 11:25 | timvisher | do you also embed an nrepl server? |
| 11:26 | timvisher | michaelr`: bet you pandoc could do it! (or at least get you stupid close) :) |
| 11:26 | timvisher | but i haven't heard of anything |
| 11:26 | justin_smith | timvisher: I use an environment variable to optionally start nrepl (local host only, ssh tunnel to connect) |
| 11:26 | timvisher | michaelr`: actually, i take that back. doesn't enlive get you very close? |
| 11:26 | timvisher | i suppose it wouldn't pretty print, but that's why clojure.pprint is a thing |
| 11:26 | bja | michaelr`, I think I've used hickory for that before |
| 11:27 | timvisher | https://github.com/cgrand/enlive |
| 11:27 | timvisher | guess it depends what you mean by clean |
| 11:27 | justin_smith | timvisher: the nrepl optionally being started in it's own thread from the function that starts the web server |
| 11:27 | timvisher | justin_smith: and then start up the nrepl server internal to the app? |
| 11:27 | timvisher | nice |
| 11:27 | michaelr` | hickory give hiccup but it's full of empty strings and empty attribute maps |
| 11:27 | justin_smith | right, the app's logic turns on the server if the env var is set |
| 11:28 | justin_smith | timvisher: one caveat that doesn't affect most of us: don't run nrepl on a machine that is actually multi-user, because anyone on the machine can access the nrepl port and get the full permissions of the user running the clojure process |
| 11:28 | justin_smith | but who uses multi user machines for anything nowadays anyway |
| 11:28 | michaelr` | i need to import html which the designer built into my om views |
| 11:29 | michaelr` | which are written in hiccup (sablono) |
| 11:29 | michaelr` | so I thought that I must not be the first to do that :) |
| 11:29 | justin_smith | michaelr`: the reason hickory gives you empty strings (or strings with spaces) is that this ensures that the rendering gives you an identical document to the intial input, whitespace and all |
| 11:30 | michaelr` | justin_smith: that's fine by me, but it doesn't help with my use case :) |
| 11:30 | justin_smith | rihgt |
| 11:30 | justin_smith | I think enlive's html-resource likely gives you a cleaner data structure |
| 11:31 | justin_smith | or whatever the function is that gives you a data structure from an html file - forgetting the name |
| 11:31 | Glenjamin | there's a list here: https://github.com/weavejester/hiccup/wiki/Converting-html-to-hiccup |
| 11:32 | justin_smith | Glenjamin: nice! |
| 11:32 | michaelr` | Glenjamin: a list!? cool |
| 11:32 | justin_smith | (inc Glenjamin) |
| 11:32 | lazybot | ⇒ 16 |
| 11:32 | Glenjamin | it's a fairly short list |
| 11:32 | bja | michaelr`, this solution on stack overflow seems to work in my repl pretty well: https://stackoverflow.com/questions/11094837/is-there-a-parser-for-html-to-hiccup-structures |
| 11:32 | bja | it uses enlive |
| 11:32 | justin_smith | still, we can assume weavejester will update it occasionally |
| 11:33 | justin_smith | bja: yeah, that's what I use (or very close to it) |
| 11:34 | michaelr` | bja: thanks, let me check that too.. |
| 13:11 | daGrevis | hi! how is lein test finding tests? i would like to split my core_test.clj into many files |
| 13:11 | daGrevis | also, are new kids using lein test or there's another better testing framework out there? |
| 13:12 | gfredericks | daGrevis: `lein test` looks through all the namespaces under /test, I think |
| 13:12 | gfredericks | so it sounds like you just want to make more namespaces |
| 13:12 | gfredericks | normally namespaces <--> files are 1-to-1, with corresponding names |
| 13:13 | gfredericks | clojure.test is fine for a lot of people; depends on your taste |
| 13:14 | daGrevis | gfredericks, okay, thanks! clojure.test works fine for me too :P |
| 13:15 | emaczen | I'm trying to update two lazySeqs in an atom with swap! |
| 13:16 | emaczen | (swap! state update-in [:waste :foundation] rest conj (first waste)) |
| 13:16 | emaczen | The keywords have the same name as the arguments passed into the method |
| 13:17 | gfredericks | I'm having trouble figuring out what you're going for there |
| 13:17 | emaczen | This swap form should do the same thing as (push (pop waste) foundation) |
| 13:17 | hiredman | emaczen: that is a race condition |
| 13:17 | emaczen | I want to update the lazySeqs given by :waste and :foundation in atom state |
| 13:18 | emaczen | I want the function rest applied to the waste (to remove the first element) and I want to put the first element of waste at the front of foundation |
| 13:19 | gfredericks | (swap! state (fn [{:keys [waste] :as current-state}] (-> current-state (update-in [:waste] rest) (update-in [:foundation] conj (first waste))))) |
| 13:20 | gfredericks | I think that's basically what you're describing; I have no idea what race condition hiredman is referring to |
| 13:20 | emaczen | gfredericks: Thanks very much! |
| 13:20 | hiredman | (swap! state update-in [:waste :foundation] rest conj (first waste)) is grabing the first of waste out side of the swap, so it isn't part of the case, so waste in the atom could change |
| 13:21 | hiredman | cas |
| 13:22 | hiredman | assuming this is in some kind of let like (let [{:keys [waste]} @state] ....) |
| 13:25 | gfredericks | ah yeah; I tripped up on passing conj to rest and didn't bother interpreting the code any further :) |
| 13:25 | gfredericks | emaczen: hiredman is right you definitely want to be careful to do all the reading inside the update function |
| 13:25 | gfredericks | which my code does |
| 13:43 | gfredericks | anybody know of anything similar to clojure.core/format but that accepts names instead of positional args? |
| 13:44 | gfredericks | I'm imagining another throwing helper (macro?) for catch-data that lets your errmsg strings reference values in your ex-data map |
| 13:45 | gfredericks | I know about strint in the incubator lib; that could sort of be twisted into the role but it's arbitrary eval so a little different |
| 13:49 | daGrevis | i'm trying to make a test setup that creates two browser instances and passes them to test each time. this is what i have so far, but it seems that deftest have no mechanism to accept params. :( https://gist.github.com/b072e75c3a3453723a5d |
| 14:17 | crack_user | hello guys |
| 14:26 | cap10morgan | given that clojure.lang.Keyword is not part of the public API, what is the idiomatic way of converting a clojure.lang.Keyword into a java.lang.String *from Java code*? |
| 14:27 | jjttjj | I have a bunch of data i need to pull from various APIs and store somewhere persistant and query somehow with clojure. It's just to figure out my taxes and i want it to be quick/easy/hacky as possible. Does this sound like a case for mongo or is there anything better? Anything that lets me just persist clojure structures without dealing with file io? |
| 14:32 | hiredman | filesystems are a thing these days |
| 14:35 | delaney | so i've been learning a bit of clojure in my spare time. something that I can't quite grok. is there a way to de/serialize persistent data structures? for example have a map, add/remove keys and store both versions to edn/fressian/etc. how do you deserialize back to the shared/persistent state where they share most of the same memory space? |
| 14:36 | LauJensen | Gents - Ive updated to the most recent version of cider, and now C-M-x no longer drops the result of eval in the repl. Is that intentional or have I borked a setting? |
| 14:36 | chouser | delaney: generally, you don't. |
| 14:37 | delaney | hmm, i was a afraid of that |
| 14:37 | delaney | once you save/load you lose a lot of the benefits it seems |
| 14:37 | chouser | if you use normal serialization (edn, fressian, transit) you'll get *one* version, and when you read it back in you'll get a whole new unshared data structure |
| 14:37 | delaney | right |
| 14:38 | delaney | is there (not 'normal)? |
| 14:38 | delaney | :P |
| 14:38 | delaney | like a memory dump |
| 14:38 | chouser | sure, you can serialize the operations applied to a value instead |
| 14:38 | delaney | so a transaction log |
| 14:38 | chouser | yup |
| 14:40 | chouser | then you could tag various versions in the transaction log, and when deserializing grab references to those tagged version. Once thats done, those tagged versions would share the memory for their common sub-values. |
| 14:40 | delaney | i work mostly in C# and trying to justify time towards clojure, but in practice having a hard time. i love the theory of it but most of the concrete examples seem easier there. sure part of it is familiarity. |
| 14:41 | chouser | immutable values have benefits, even in contexts where you don't get structural sharing |
| 14:41 | delaney | well yeah, but i already do that in C# |
| 14:41 | chouser | in fact, structural sharing isn't really a benefit so much as an attempt to reduce the cost |
| 14:41 | delaney | but more from convention than lang level granted |
| 14:42 | chouser | ah, well, if you've already got immutability and high-order functions, that is indeed a couple of major talking points removed in an argument for clojure |
| 14:42 | delaney | but there is no D in stm's acid beyond things like datomic it seems |
| 14:42 | chouser | let's see, what's left -- immutable locals, s-expressions (macros), ... |
| 14:43 | delaney | yeah i like the idea of Om, which is what got me interested in clojure (already using react from js land) |
| 14:45 | agarman_ | C# is a good language, especially as unnecessary syntax keeps getting pruned away each release |
| 14:46 | delaney | agarman_: right. if it was a while ago then yeah there is a big diff (and being tied to jvm for sure). maybe its also when looking at the clojure examples or tutorials it just is crazy terse to grok |
| 14:46 | delaney | the syntax is simple, the complexity moves into the function calls |
| 14:47 | delaney | again hopefully that melts away with time |
| 14:47 | delaney | i love the idea of having the same lang server and client side for sure, and edn seems slicker than json for my wants |
| 14:49 | agarman_ | if you have an opportunity to learn F#, and force yourself to not use mutable (mostly records, tuples & object expressions) you'll have most of the big benefits of Clojure. |
| 14:51 | delaney | well i've always loved the jvm's speed, just not the root lang. the clojurescript and even closure-clr makes it seem like there is something there i just don't quite see yet. in no way was it trying to avoid clojure, if anything seeing if i'm just approaching it wrong. |
| 14:51 | agarman_ | Clojure's atoms & refs are nice though. core.async is great too. |
| 14:55 | agarman_ | Even though C# & F# have syntax trees, reflection emit & reified generic containers these are poor substitutes for a good macro system. |
| 14:59 | delaney | i sounds dumb but i can't see my need for macros. i know there are canonical examples like (what if you want to write 'if') |
| 14:59 | delaney | i see they help you basically write compilers, but for the stuff i do it seems weird |
| 14:59 | LauJensen | Gents - Ive updated to the most recent version of cider, and now C-M-x no longer drops the result of eval in the repl. Is that intentional or have I borked a setting? |
| 15:00 | delaney | like you can't write a macro that does matrix math faster by preprocessing |
| 15:02 | agarman_ | delaney: C# delegates are all syntactic sugar put in by the special logic in the compiler. If you had macros in C#, you could write that. |
| 15:03 | agarman_ | delaney: C# async methods, dynamics, var & many many other items are written as changes to the C# compiler. These could all be done via a library if C# supported macros. |
| 15:04 | delaney | i get that, but those constructs are there now. could you write a macro that does that transaction log thing i was talking about before. |
| 15:04 | delaney | take every map/array function and throw into a transact log? |
| 15:06 | amalloy | delaney: for one thing, the compiler would be a lot simpler if it *didn't* have to include that stuff, and could let macros do it instead |
| 15:06 | amalloy | but if you are looking for a simple useful example, i offer https://github.com/amalloy/useful/blob/96f665/src/flatland/useful/map.clj#L6 |
| 15:06 | amalloy | so that you can write (keyed [x y z]) instead of {:x x, :y y, :z z} |
| 15:07 | agarman_ | delaney: you can do a write to transact log in Clojure but you'd usually do it by wrapping the vars that make the changes rather than writing macros |
| 15:10 | agarman_ | but that logs operations on map/vector functions instead |
| 15:13 | delaney | so why wouldn't you do as a macro? |
| 15:18 | agarman_ | it may be implemented with macros, but the better usage would be to (transact-log/start) and have that rewrite the vars for the functions that are relevant. So when someone calls (conj ...), (map ...), etc you get your transaction log written without having to change existing calls. It's like AoP but with all of your language already in an IOC container |
| 15:18 | amalloy | i don't know that a mass modification of vars is really such a great solution either... |
| 15:19 | agarman_ | amalloy: It would terrify me. |
| 15:20 | agarman_ | for debugging purposes, not so scary. |
| 15:20 | amalloy | i disagree. conj and map are called *a lot*. i'd be surprised if you could even get meaningful debug output by modifying their vars, given how much they're called by the standard library |
| 15:20 | amalloy | like, map calls map |
| 15:21 | agarman_ | true |
| 15:22 | amalloy | well, at least java's logging libraries let you turn on debug logging for particular classes/packages individually |
| 15:23 | agarman_ | yep |
| 15:23 | agarman_ | that was an accident of trying to use matthias's inspect library on a piece of clojure in the big Java app |
| 18:25 | emaczen | can you multi-method dispatch on just keywords? |
| 18:26 | arrdem | sure if your dispatch operation is clojure.core/identity |
| 18:26 | emaczen | I'm thinking if my user clicks on two places, then I can make a set of functions for each two-combination |
| 18:27 | emaczen | arrdem: can you give me an example? |
| 18:28 | emaczen | I'm very new to this |
| 18:28 | arrdem | yeah sure one minute |
| 18:31 | arrdem | emaczen: https://www.refheap.com/98087 |
| 18:31 | arrdem | emaczen: is that helpful? |
| 18:31 | emaczen | arrdem: Thanks, I will try this out |
| 18:32 | emaczen | how will this work for pairs? |
| 18:32 | emaczen | pairs of keywords? |
| 18:33 | arrdem | emaczen: the dispatch-fn is applied to all arguments. |
| 18:33 | arrdem | emaczen: so try invoking that function with a pair [:foo :bar] |
| 18:34 | emaczen | For this line: (defmethod identity-dispatch :foo [foo] "Got a foo!") |
| 18:35 | emaczen | what is the type of foo inside the [] ? |
| 18:35 | arrdem | emaczen: foo is simply a symbol naming the value of the 1st and in this case only argument. |
| 18:41 | emaczen | arrdem: I keep getting 'No method in multimethod 'pop-pushable?' for dispatch value: [nil |
| 18:41 | emaczen | nil]; |
| 18:41 | emaczen | how do I call these methods exactly? |
| 18:41 | emaczen | I'll try wrapping them in a vector first |
| 18:42 | emaczen | That didn't work either |
| 18:42 | arrdem | emaczen: can you give me a sample input pair? |
| 18:43 | arrdem | emaczen: (pop-pushable :foo :bar) or (pop-pushable [:foo :bar]) |
| 18:43 | emaczen | I tried both of those |
| 18:44 | arrdem | emaczen: in the form (defmethod identity-dispatch :foo [foo] "Got a foo!") the keyword :foo is the dispatch value for which the method tail returning the strung (fn [foo] "Got a foo!") will be invoked. |
| 18:44 | arrdem | emaczen: when you invoke a dispatch identity multimethod with the pair [:foo :bar], you need to have a method registered for that pair. |
| 18:45 | arrdem | bah I'm sorry I'm doing this wrong. |
| 18:45 | arrdem | emaczen: can you refheap what you have now? |
| 18:46 | emaczen | arrdem: Sure, I am trying to make a klondike solitaire game |
| 18:46 | emaczen | Can you look at a pastebin? |
| 18:46 | arrdem | sure |
| 18:49 | emaczen | arrdem: http://paste.lisp.org/+34P1. |
| 18:50 | emaczen | arrdem: do you get the idea? |
| 18:50 | arrdem | emaczen: yeah. |
| 18:51 | arrdem | emaczen: (waste @state) could be :waste, unless there's more code you didn't paste. |
| 18:51 | justin_smith | emaczen: the args to your defmulti and your defmethod don't agree in arity |
| 18:52 | justin_smith | arrdem: based on the dispatch it would have to be (::waste @state), which looks like it would always be nil |
| 18:53 | arrdem | Ah. @justin_smith yeah I see the arity missmatch. |
| 18:53 | emaczen | What is the arity mismatch? |
| 18:54 | justin_smith | emaczen: your multi takes one arg, the method you create for it takes two |
| 18:54 | justin_smith | identity isn't a two argument function, but your defmethod is |
| 18:54 | emaczen | I'm not even sure why the multi takes one.... All I did was make the dispatch function be identity |
| 18:54 | arrdem | emaczen: if you dispatch on the _pair_ [::waste ::foundation], you have only given the body one argument. |
| 18:54 | justin_smith | emaczen: and identity takes two arguments |
| 18:55 | justin_smith | emaczen: you could change your dispatch function to be vector |
| 18:55 | justin_smith | and then the arities would work |
| 18:55 | justin_smith | (defmulti pop-pushable? vector) |
| 18:55 | justin_smith | because you can call vector on two args, and it returns the two args such that you can dispatch on them |
| 18:56 | justin_smith | or maybe list would be better, it would work the same either way |
| 18:57 | arrdem | justin_smith: dispatching on first should be fine... |
| 18:57 | arrdem | justin_smith: in case you want non-constant args elsewhere :P |
| 18:57 | justin_smith | arrdem: he matches on two args though |
| 18:57 | emaczen | give me a few seconds/minutes -- I am following, but I know this is going to take me a little bit of time to get to work |
| 18:57 | arrdem | justin_smith: (foo [dispatch-a dispatch-b] . args) |
| 18:57 | amalloy | arrdem: (first x y) doesn't return x |
| 18:58 | arrdem | amalloy: correct me if I'm wrong, but I thought that multimethods did (<dispatch-fn> (seq args)) |
| 18:58 | arrdem | not (apply <dispatch-fn> args) |
| 18:58 | amalloy | arrdem: that is wrong |
| 18:59 | amalloy | the dispatch fn receives exactly the same args as the method does |
| 19:00 | justin_smith | arrdem: emaczen: https://www.refheap.com/98090 |
| 19:00 | justin_smith | that's how you dispatch on two arguments |
| 19:00 | arrdem | "This function will be applied to the arguments to the multimethod in order to produce a dispatching value." |
| 19:00 | arrdem | gotcha., |
| 19:00 | arrdem | on clojure.org/multimethods but not in the docstring. right. |
| 19:00 | emaczen | justin_smith: cool! |
| 19:01 | emaczen | I have a new question now... |
| 19:01 | emaczen | I want to dispatch on these two keywords and an integer |
| 19:01 | emaczen | err wait |
| 19:01 | emaczen | sorry |
| 19:02 | justin_smith | (fn [a b & optional] [a b]) |
| 19:02 | justin_smith | it will dispatch on the first two, and the multi itself will get all the args |
| 19:02 | emaczen | I just want the integer to be an argument to the function |
| 19:02 | justin_smith | they are all arguments |
| 19:03 | justin_smith | for clarity, when I said "the multi itself" I mean the form defined in defmethod, that was badly worded |
| 19:03 | emaczen | Wait, (defmethod foo [:a :b] [a b i] ... ) |
| 19:03 | justin_smith | right |
| 19:04 | emaczen | cool! |
| 19:04 | justin_smith | that would work with the dispatch function I shared above |
| 19:04 | justin_smith | because the dispatch just checks the first two args, ignoring the rest |
| 19:04 | dfletcher | Ahhh sweet. UI editable with WindowBuilder, main program logic in Clojure. This is what I was after, thanks for the help earlier channel :) |
| 19:05 | justin_smith | emaczen: updated the paste to show optional args on a defmulti https://www.refheap.com/98090 |
| 19:06 | justin_smith | dfletcher: sounds cool, I would like to read it |
| 19:07 | emaczen | justin_smith: sweet |
| 19:10 | emaczen | how do I remove a defmulti definition from the REPL |
| 19:10 | rufoa | you can use interop to do (.addMethod |
| 19:10 | rufoa | so perhaps similar |
| 19:11 | rufoa | look in clojure.lang.MultiFn |
| 19:11 | arrdem | $grim clojure.core/remove-all-methods |
| 19:11 | lazybot | http://grimoire.arrdem.com/1.6.0/clojure.core/remove-all-methods |
| 19:11 | justin_smith | emaczen: it is a def, you can do (def multi-fn-name nil) |
| 19:11 | arrdem | $grim clojure.core/remove-method |
| 19:11 | lazybot | http://grimoire.arrdem.com/1.6.0/clojure.core/remove-method |
| 19:11 | dfletcher | heh oops justin_smith wrong chan. #eclipse helped me figure out how to make this work ;) |
| 19:11 | justin_smith | haha |
| 19:11 | justin_smith | OK |
| 19:11 | justin_smith | dfletcher: is it a clojure thing at all? |
| 19:12 | emaczen | arrdem: doesn't that just remove all the methods of the multi? |
| 19:12 | arrdem | emaczen: remove-method can remove the method associated with a specific dispatch value. |
| 19:12 | dfletcher | my main program logic is in clojure and i pass a window to my clojure main (that was built using some nice gui tools in Eclipse [WindowBuilder]) |
| 19:12 | justin_smith | emaczen: arrdem: to remove the mutli altogether just do (def your-multi nil) |
| 19:13 | justin_smith | *multi |
| 19:13 | dfletcher | actually heh maybe I don't even want to pass the window here. but as a test (.show window) is working nicely :> |
| 19:13 | emaczen | thanks! |
| 19:13 | justin_smith | this is needed in order to redefine multis, because they are defonce |
| 19:14 | justin_smith | that's a trick I learned from technomancy, hope he joins us here again some day |
| 19:15 | emaczen | isn't technomancy on #emacs a lot? |
| 19:15 | justin_smith | yeah, he seems to be taking a break from this channel |
| 19:16 | amalloy | $karma technomancy |
| 19:16 | lazybot | technomancy has karma 162. |
| 19:16 | godd2 | I just ordered his keyboard a week and a half ago. can't wait to solder that together |
| 19:18 | godd2 | This one, if anyone's interested: http://atreus.technomancy.us/ |
| 19:23 | emaczen | justin_smith: I'm still struggling and I'm following your example practically to a tee |
| 19:23 | justin_smith | emaczen: is there a specific thing that isn't working? |
| 19:24 | emaczen | I'll make a paste |
| 19:26 | emaczen | https://www.refheap.com/98091 |
| 19:26 | emaczen | I am calling the method like: (pop-pushable? [::waste ::foundation] 2) |
| 19:27 | justin_smith | emaczen: why the vector? |
| 19:27 | justin_smith | (pop-pushable? ::waste ::foundation 2) |
| 19:27 | justin_smith | should work with the definitions you have there |
| 19:27 | emaczen | I tried it like that too and it still says wrong number of args |
| 19:28 | emaczen | I'm going to try restarting my repl |
| 19:28 | justin_smith | did you do (def pop-pushable? nil) before redefining the defmulti? |
| 19:29 | justin_smith | because just running defmulti again will not replace the old dispatch |
| 19:29 | justin_smith | it's varargs, it should only complain about argument count if you provide less than 2 args |
| 19:29 | emaczen | justin_smith: yeah, I didn't set it to nil |
| 19:30 | justin_smith | $source defmulti |
| 19:31 | lazybot | defmulti is http://is.gd/nhS5dG |
| 19:31 | justin_smith | emaczen: look at the when-not near the bottom of the definition of defmulti |
| 19:31 | justin_smith | it doesn' |
| 19:31 | justin_smith | t do anything if the multi is already a multi |
| 19:31 | justin_smith | so assigning to nil explicitly is needed in order to redefine the dispatch |
| 19:32 | justin_smith | well, asigning to anything that is not a multimethod, or deleting the var itself from the namespace |
| 19:32 | justin_smith | but the former is easier |
| 19:33 | emaczen | I get a null pointer exception now |
| 19:34 | justin_smith | you need to redefine the multifn and it's methods after assigning to nil |
| 19:34 | emaczen | justin_smith: I think this is actually in the definition of my multi-method... lol |
| 19:34 | emaczen | I'll keep playing with it |
| 19:34 | justin_smith | oh, OK then :) |
| 19:35 | justin_smith | here's a funny one: |
| 19:35 | blake_ | Can map return a map? =P |
| 19:35 | justin_smith | ,(nth nil 2) |
| 19:35 | clojurebot | nil |
| 19:35 | justin_smith | ,(nth () 2) |
| 19:35 | clojurebot | #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException> |
| 19:36 | justin_smith | blake_: you can use (into {} (map ...)) |
| 19:36 | justin_smith | that makes the map eager of course, because {} cannot be lazy |
| 19:36 | blake_ | justin_smith: Sure, I was just noting the lexical oddity. |
| 19:36 | justin_smith | ahh, OK |
| 19:36 | justin_smith | yeah, that bugs me sometimes |
| 19:37 | blake_ | Homophones, man. How do they work? |
| 19:37 | amalloy | obviously we should just call them dictionaries |
| 19:37 | amalloy | i think these are actually hononyms, right, not just homophones |
| 19:37 | justin_smith | ,(def territory {}) |
| 19:37 | clojurebot | #'sandbox/territory |
| 19:37 | blake_ | Yes. There's also "associative arrays", though 'tis cumbersome. |
| 19:37 | justin_smith | amalloy: homonym |
| 19:38 | justin_smith | oh, they are homophones too |
| 19:38 | justin_smith | as many homonyms are |
| 19:38 | blake_ | justin_smith: All homophones are homonyms. No, strike that, reverse it. |
| 19:38 | blake_ | ALl homonyms ar ehomophones. |
| 19:38 | amalloy | blake_: injective cartesian relations |
| 19:38 | justin_smith | there are homophones that are not homonyms |
| 19:38 | justin_smith | there are homonyms that are not homophones |
| 19:38 | justin_smith | like read |
| 19:38 | blake_ | amalloy: That's good jargon! |
| 19:38 | justin_smith | that is homonym but not homophone |
| 19:39 | blake_ | justin_smith: Well, but not at the same time. |
| 19:39 | emaczen | clojure.core/swap! |
| 19:39 | emaczen | ([atom f] [atom f x] [atom f x y] [atom f x y & args]) |
| 19:39 | amalloy | blake_: huh? |
| 19:39 | blake_ | justin_smith: If you're saying "red" and "reed", they're no longer homonyms (or homophones). |
| 19:39 | justin_smith | I'm just saying, all four options are available: a, b, both a and b, neither a nor b |
| 19:39 | emaczen | What do the the different vectors [atom f] [atom f x] mean? |
| 19:40 | justin_smith | blake_: I mean "I read it" and "I will read it" |
| 19:40 | emaczen | different possible inputs? |
| 19:40 | emaczen | method overloading I mean? |
| 19:40 | justin_smith | emaczen: possible arities of a function |
| 19:40 | blake_ | amalloy: lol, sorry, I thought you were suggesting "injective cartesian relations" as a new way of saying "map". |
| 19:40 | justin_smith | emaczen the only kind of overloading we have is argument count |
| 19:40 | amalloy | blake_: i was |
| 19:40 | amalloy | i'm objecting to your homonym/homophone claims |
| 19:41 | amalloy | justin_smith: lead and lead are probably a better example, since read and read have similar origins/meanings |
| 19:41 | justin_smith | much better example, thanks |
| 19:41 | blake_ | amalloy: Homophones include homonyms, if I'm not mistaken. Homonyms are homophones that are spelled the same. |
| 19:41 | amalloy | blake_: no. homophones are pronounced the same (as the -phone suffix suggests) |
| 19:41 | justin_smith | blake_: no, I already explained |
| 19:42 | amalloy | homonyms are spelled the same |
| 19:42 | justin_smith | some homophones are homonyms, but not all, some homonyms are homophones, but not all |
| 19:43 | amalloy | what i don't quite get is the difference between a homonym and homograph |
| 19:43 | blake_ | Mmmmmm. OK, we're using different definitions. "lead" and "lead" are homographs. |
| 19:43 | justin_smith | blake_: these words are in the dictionary |
| 19:44 | blake_ | Sorry, this is my default: |
| 19:44 | blake_ | In non-technical contexts, the term "homonym" may be used (somewhat confusingly) to refer to words that are either homographs or homophones. |
| 19:44 | blake_ | http://en.wikipedia.org/wiki/Homonym |
| 19:44 | justin_smith | blake_: homograph is a synonym for homonym |
| 19:44 | blake_ | I recommend that page there. |
| 19:45 | emaczen | what does {:keys [some variable]} do? |
| 19:45 | justin_smith | emaczen: argument destructuring by keyword |
| 19:45 | justin_smith | ,(let [{:keys [a b]} {:a 1 :b 2}] (+ a b)) |
| 19:45 | clojurebot | 3 |
| 19:46 | justin_smith | blake_: fascinating, I didn't realize that more technical definition existed |
| 19:47 | blake_ | justin_smith: Yeah. It actually is a lot better than the common definition, which causes much confusion. |
| 19:47 | justin_smith | (inc blake__ |
| 19:47 | justin_smith | err |
| 19:47 | justin_smith | (inc blake_) |
| 19:47 | lazybot | ⇒ 1 |
| 19:47 | blake_ | (Or, when some jackass uses the non-common definition without quailfying.) |
| 19:47 | justin_smith | wat |
| 19:47 | blake_ | lol |
| 19:47 | blake_ | I lost my braces. |
| 19:47 | blake_ | (inc {blake}) |
| 19:47 | lazybot | ⇒ 2 |
| 19:47 | blake_ | lol |
| 19:47 | blake_ | THE LOOPHOLE! |
| 19:48 | justin_smith | what was that unicode? I am in a tty and I just got a replacement character |
| 19:48 | justin_smith | (identity blake_) |
| 19:48 | lazybot | blake_ has karma 1. |
| 19:49 | emaczen | ,(def m {:a 1 :b 2 :c 3}) |
| 19:49 | clojurebot | #'sandbox/m |
| 19:49 | emaczen | (update-in m :a (fn [x] (+ x 1))) |
| 19:49 | emaczen | ,(update-in m :a (fn [x] (+ x 1))) |
| 19:49 | clojurebot | #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Keyword> |
| 19:50 | emaczen | why doesn't that work? |
| 19:50 | justin_smith | emaczen: [:a] |
| 19:50 | amalloy | emaczen: you are forgetting the brackets again |
| 19:50 | emaczen | thanks guys! |
| 19:56 | blake_ | For finding all the unique keys in a sequence of maps "(keys (apply merge x1))". Tacky? |
| 19:59 | emaczen | I need to update two lazySeqs in an atom -- I want to remove the first element of one of the lazySeqs and conjoin it to the front of the other. |
| 19:59 | emaczen | Can you guys give me some advice? |
| 20:00 | emaczen | swap! only takes one function |
| 20:00 | amalloy | emaczen: write a pure function that takes in two lazy seqs and returns two new ones |
| 20:00 | amalloy | forgetting about the atom entirely |
| 20:00 | amalloy | then, once that works, adapt it to your atom |
| 20:04 | emaczen | amalloy: I made my function, now how do I correctly pass the arguments? |
| 20:04 | justin_smith | it should have exactly one argument |
| 20:05 | emaczen | (defn pop-push [l1 l2] [(rest l1) (conj l2 (first l1))]) |
| 20:05 | emaczen | That is my function |
| 20:05 | amalloy | emaczen: what is in your atom, and what does your function look like? |
| 20:06 | emaczen | amalloy: there are two lazySeqs (lists) in the Atom that are relevant for pop-push |
| 20:06 | amalloy | emaczen: write your function so that it takes as input exactly whatever object is currently in the atom. like, how are you storing two things in one atom? as a list? then your function should take a list and return a list. as a map? then your function should take a map and return a map |
| 20:07 | emaczen | amalloy: The atom is a map |
| 20:12 | vas | Hi. I want to have short-ids for a bunch of posts that live in a datomic database. I am thinking maybe I can devise a hash function that will figure out the entity ID from the letters and numbers of the short ID (for example, 17592186045438 would map to a667qq2 or some such). Is this a reasonable approach? |
| 20:13 | justin_smith | vas: what would you do to handle collisions? |
| 20:14 | emaczen | amalloy: The two lazySeqs (lists) are values in the map? |
| 20:14 | emaczen | (defn pop-push [l1 l2] [(rest l1) (conj l2 (first l1))]) |
| 20:14 | vas | justin_smith: excellent point. does it make more sense to add a unique identifier "on the fly" to the datomic entities? |
| 20:14 | vas | (and maybe just go incrementally?) |
| 20:15 | justin_smith | vas: that would likely be simpler |
| 20:15 | vas | you got some good words in them fingers. thanks yet again friend |
| 20:16 | justin_smith | unless there is some clever scheme for short IDs that handle collisions elegantly (for all I know there might be), in which case use that of course |
| 20:16 | justin_smith | I try |
| 20:16 | emaczen | amalloy: should pop-push take a map? Or should it take two lists? |
| 20:16 | amalloy | emaczen: it should take exactly what is in your atom |
| 20:16 | justin_smith | emaczen: if you want to update a map, have it take a map |
| 20:18 | emaczen | I'm trying to use swap! |
| 20:18 | emaczen | So I am trying to make the function that swap! takes |
| 20:18 | justin_smith | in that case, have it take a map, and return one |
| 20:19 | emaczen | justin_smith: I will try that |
| 20:22 | emaczen | (defn pop-push [m] |
| 20:22 | emaczen | (update-in m [:waste] (fn [] (conj (first (:deck @state)) (:waste @state)))) |
| 20:22 | emaczen | (update-in m [:deck] rest)) |
| 20:22 | emaczen | Oops |
| 20:22 | justin_smith | emaczen: that would work if you chained it using -> |
| 20:22 | emaczen | I'll make a paste for this |
| 20:22 | amalloy | emaczen: remember, this is a pure function. it doesn't take in an atom of a map, but a map |
| 20:23 | amalloy | justin_smith: no, there are at least two other things wrong |
| 20:23 | justin_smith | yes, you are right |
| 20:24 | amalloy | emaczen: try what i was suggesting: forget about the atom entirely. (def sample-map '{:waste (1 2 3) :deck (4 5 6)}), and then write a function that takes in sample-map and returns a new map the way you want it |
| 20:24 | emaczen | so I removed, the dereferencing |
| 20:24 | amalloy | once you have that, the atom will be super-easy to add |
| 20:25 | justin_smith | emaczen: you want no reference to the state global |
| 20:25 | justin_smith | just use the map that gets passed in |
| 20:25 | emaczen | Okay, let me try this again |
| 20:25 | ludbek | does anyone here know how to use clojurescript for meteor development? |
| 20:26 | godd2 | ludbek quick google leads to meteor-clojurescript: https://github.com/mystor/meteor-clojurescript |
| 20:27 | emaczen | (defn pop-push [m] |
| 20:27 | emaczen | {:waste (conj (:waste m) (first (:deck m))) |
| 20:27 | emaczen | :deck (rest (:deck m))}) |
| 20:27 | emaczen | How about that? |
| 20:27 | ludbek | @godd2, i tried it, but the compiled code some 27k big |
| 20:27 | ludbek | @godd2 is it supposed to be so? |
| 20:28 | justin_smith | emaczen: if you use -> chained update-in, (or at least a merge) it would work even if you added more keys to the map |
| 20:28 | amalloy | emaczen: that looks pretty good to me |
| 20:28 | godd2 | ludbek No clue. You might be able to tweet ben orenstein and ask him. I know he does a lot of clojurescript as of late |
| 20:28 | justin_smith | emaczen: it's really common to add keys to a map, so code that needs to be edited to add the extra keys is often regretted |
| 20:28 | amalloy | emaczen: that function should now just work: (swap! some-atom pop-push) |
| 20:29 | emaczen | justin_smith: I'll try the chained variant once this works |
| 20:30 | emaczen | amalloy: Thanks so much! This should take me pretty far :D |
| 20:32 | ludbek | @godd2 thanks |
| 20:45 | emaczen | justin_smith: the other function that I was asking about first works too :) |
| 20:45 | emaczen | thanks so much guys! |
| 20:46 | gfredericks | does anybody know of an approach to using schema or something similar to describe coersions as well as vanilla schemas? |
| 20:49 | justin_smith | emaczen: it shouldn't, unless the update-ins are chained with -> |
| 20:49 | justin_smith | emaczen: or is that what you mean? |
| 20:50 | emaczen | I'm not using update-ins. |
| 20:51 | justin_smith | oh, I thought that was what you meant by the other function |
| 20:51 | emaczen | (fn [m] |
| 20:51 | emaczen | {:waste (conj (:waste m) (nth n (:deck m))) |
| 20:51 | emaczen | :deck (nthrest (:deck m) n)}))) |
| 20:51 | emaczen | I'm doing that |
| 20:51 | emaczen | other function refers to the multi-method questions I had earlier |
| 20:51 | justin_smith | oh, OK |
| 21:02 | emaczen | how can I get the first 3 elements of a list? |
| 21:02 | emaczen | Is there a function like nthrest? |
| 21:02 | justin_smith | (take 3 l) |
| 21:03 | emaczen | cool! |
| 21:04 | amalloy | nthrest is the opposite, it would remove the first 3 |
| 21:04 | justin_smith | when would you use nthrest instead of drop? |
| 21:05 | amalloy | probably never. but they have different laziness characteristics |
| 21:05 | justin_smith | where drop is lazier? |
| 21:05 | amalloy | so in theory you might have situations where you'd prefer nthrest |
| 21:05 | amalloy | yeah |
| 21:15 | xapak | Hello. |
| 21:17 | xapak | I’m new to Clojure (I may have tried it before, but this time is for real), and I’d like to know what projects do you recommend to check their source code for “elegantness” and “succinctness”. I’ve been tasked to do a CLI, but also the library part of it (functional), so I’d like to follow some code guideliness besides just the Best Practices on “paper”. |
| 21:20 | emaczen | justin_smith: how can I define two optional paramters to a multi? |
| 21:21 | emaczen | I tried just adding another argument as well placing another & |
| 21:34 | justin_smith | all the args after the first two are put in one collection |
| 21:35 | justin_smith | ,((fn [& args] args) 1 2 3 4) |
| 21:35 | clojurebot | (1 2 3 4) |
| 21:35 | emaczen | is it treated as var args or as a list inside the function? |
| 21:36 | justin_smith | it is var args, which means that inside the function it is a list |
| 21:36 | emaczen | There isn't another way to do it? |
| 21:36 | justin_smith | you can use destructuring |
| 21:36 | justin_smith | but that's just destructuring the list |
| 21:37 | justin_smith | ,((fn [& [a b c]] c) 1 2 3) |
| 21:37 | clojurebot | 3 |
| 21:37 | emaczen | justin_smith: cool! I'm happy with that |
| 21:51 | skynet9001 | is there a good way to see out of date dependencies in a lein project? |
| 21:52 | gfredericks | lein ancient |
| 21:52 | gfredericks | which might be a plugin |
| 21:52 | skynet9001 | thanks |
| 21:52 | gfredericks | np |
| 21:53 | xapak | I’ll ask again in case it was missed: |
| 21:53 | xapak | I’m new to Clojure (I may have tried it before, but this time is for real), and I’d like to know what projects do you recommend to check their source code for “elegantness” and “succinctness”. I’ve been tasked to do a CLI, but also the library part of it (functional), so I’d like to follow some code guideliness besides just the Best Practices on “paper”. |
| 21:55 | justin_smith | xapak: flatland/useful, the various ring libraries, pretty much anything from prismatic |
| 21:56 | xapak | Prismatic... I seem to have heard or something from them before. |
| 21:56 | xapak | justin_smith, awesome, thanks. :) |
| 21:56 | justin_smith | xapak: they make schema, plumbing, and graph |
| 22:05 | skynet9001 | anyone here use the chestnut webapp template? |
| 22:20 | skynet9001 | I'm getting "ReferenceError: goog is not defined" after using lein ring uberwar on a chestnut project and deploying on tomcat, any ideas? |
| 22:21 | justin_smith | skynet9001: how are you building your cljs? are you turning on optimizations? |
| 22:22 | skynet9001 | justin_smith: looks like :optimizations :none |
| 22:23 | justin_smith | try running 'lein with-profile -dev,+uberjar cljsbuild once' before making the uberwar |
| 22:26 | skynet9001 | will try that, thanks |
| 22:31 | skynet9001 | so that didn't work, but I'm looking at the /public/js/ directory and it's missing the out.js.map file, although I have :sourcemap "resources/public/js/out.js.map" defined in the cljs build |
| 22:32 | skynet9001 | I don't see the resources/public/js/out.js.map file in the project, how do I create it? |
| 22:42 | justin_smith | cljsbuild should create that. maybe cljsbuild clean then build again? |
| 23:03 | skynet9001 | still nothing, weird |
| 23:03 | skynet9001 | I had it working on another machine earlier today, maybe something's misconfigured on this vm |
| 23:04 | skynet9001 | this is all just the base chestnut template |
| 23:07 | justin_smith | I don't see what vm config could break chestnut |
| 23:08 | skynet9001 | I think on this one I had installed openjdk 8 before installing 7, maybe that had something to do with it |
| 23:08 | skynet9001 | gonna try a fresh start |
| 23:20 | Guthur | Hi, I'm trying to create my own leningen template standard-project. I created the project with lein new template standard-project editted it and then ran lein install |
| 23:20 | Guthur | there were no errors but when I try to use my template with lein new standard-project foo it gives the following... |
| 23:20 | Guthur | Failed to resolve version for standard-project:lein-template:jar:RELEASE |
| 23:21 | Guthur | any suggestions? |
| 23:27 | ddellacosta | is there a reason to use atoms vs. dynamic vars for configuration of libs? |
| 23:27 | ddellacosta | or even something else? |
| 23:33 | justin_smith | ddellacosta: a global atom will usually limit how a lib can be used |
| 23:35 | ddellacosta | justin_smith: so, if I make configuration an atom, that's going to ensure that/restrict it so that the configuration is accessible across threads, no? |
| 23:35 | ddellacosta | vs. dynamic vars being thread-local--that's the big distinction, am I right? |
| 23:35 | justin_smith | I think the cleanest is the c.j.jdbc approach of a configuration arg, that a client can esaily partially apply |
| 23:38 | justin_smith | yeah, an atom means a global config, dynamic vars, thresd local, configuration argument is lexically scoped |
| 23:38 | ddellacosta | justin_smith: trying to understand what you mean here--you're talking basically about config always getting passed in as fn args, basically? |
| 23:38 | ddellacosta | justin_smith: in reference to c.j.j being ideal |
| 23:38 | ddellacosta | (if that's the case would agree) |
| 23:38 | justin_smith | a map ad the first arg, yeah |
| 23:39 | justin_smith | the first, because we have partial |
| 23:43 | justin_smith | the atom and dynamic var versions can be implemented by the end user in two lines of code |
| 23:43 | justin_smith | (given the explicit argument version existing, and taking the config as the first arg) |
| 23:44 | justin_smith | the others are not so flexible |