2015-03-02
| 00:47 | Shayanjm | What's the difference between doto & ->? |
| 00:53 | puredanger | doto applies each expression separately without threading the result because it expects to be calling side-effecting functions |
| 00:53 | _kardan | doto cascaded calls & -> chained calls |
| 00:53 | puredanger | which is what you commonly get with Java setters |
| 00:58 | TimMc | &(clojure.walk/macroexpand-all '(-> a (b 1) (c 2))) |
| 00:58 | lazybot | ⇒ (c (b a 1) 2) |
| 00:58 | TimMc | &(clojure.walk/macroexpand-all '(doto a (b 1) (c 2))) |
| 00:58 | lazybot | ⇒ (let* [G__13521 a] (b G__13521 1) (c G__13521 2) G__13521) |
| 01:31 | jon__ | getting started with clojure |
| 02:48 | bucketh3ad | Is it a good idea to use pmap to run a get/parse function over a list of uri's, or is there a better tool for such a task? |
| 02:51 | TEttinger | bucketh3ad, I think pmap is mostly for cpu-limited computations that need multiple threads, not things that need multiple network connections? |
| 02:51 | TEttinger | I haven't done much with remote getting of content |
| 03:38 | zot | morning all. i'm having a dumb moment, and hoping that somebody here might have the eyes to combat my blindness. i'm working up a "simple" core.async model for kafka, intended to work with the component library. it's failing miserably, despite having tried to model it off my other working async pub/sub code. i've stripped out the stop code, and made it self standing (instead of component based). the 'send-message' at the end returns, and the ' |
| 03:40 | TEttinger | message cut off after: end returns, and the ' |
| 03:40 | TEttinger | ^ zot |
| 03:41 | zot | the 'send-message' at the end returns, and the 'recv-message' just sits waiting. any clues? https://gist.github.com/anonymous/b639bddfe1f7ea646b1f |
| 03:42 | zot | (also, i would gladly take ideas and suggestions as to how experienced clojurists debug this sort of thing — i'm a bit clueless when debugging async, etc., code in clojure.) |
| 03:43 | sveri | zot: not sure about this, but I think I read somewhere you have to take extra steps to get stacktraces from async code |
| 03:43 | zot | i can't even tell if a stacktrace is the problem, or if i'm "doing it wrong" wrt pub/sub in core.async |
| 05:33 | zot | ftr, it was something stupid: (async/pub was being called w/ (:publisher this), which is empty at that point in execution.) |
| 06:16 | devll | hi,I am using Component for my project. |
| 06:16 | devll | and calling (.stop (:server component)) in (stop [this ..]) |
| 06:16 | devll | wont work. |
| 06:17 | devll | full code is here. http://pastebin.com/FLhSw2MY |
| 06:17 | devll | why? |
| 06:17 | clojurebot | why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone |
| 06:18 | devll | could anyone explain this to me? thanks. |
| 06:20 | devll | justin_smith: ? |
| 06:21 | TEttinger | hey devll |
| 06:21 | TEttinger | I'll take a look |
| 06:21 | devll | hi TEttinger ,thanks |
| 06:21 | TEttinger | also, define "won't work" |
| 06:21 | devll | throws an exception. |
| 06:22 | TEttinger | when you (println (:server component)) , can you also print the (class component) and (class (:server component)) ? |
| 06:23 | TEttinger | also, which exception |
| 06:23 | TEttinger | NPE would be good to know if it's that |
| 06:23 | devll | the code I posted works. |
| 06:23 | devll | I commented out one line. |
| 06:24 | brkpnt | Hi, there is an equivalent way to load a whole project like in Common Lisp asdf:load-system? In other ways to compile my whole project and load it to the repl? |
| 06:24 | devll | which throws exception if I use it instead of close-jetty function |
| 06:24 | brkpnt | ways->words* |
| 06:25 | devll | brkpnt: tools.namespace maybe help. |
| 06:26 | TEttinger | brkpnt: setting the :main ns may also help in project.clj |
| 06:26 | clojurebot | Excuse me? |
| 06:26 | devll | (:server component) is a org.eclipse.jetty.server.Server |
| 06:27 | TEttinger | and which exception? |
| 06:27 | devll | wait a sec. |
| 06:28 | TEttinger | it doesn't have a .stop method |
| 06:28 | TEttinger | http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/server/Server.html |
| 06:28 | TEttinger | there's doStop |
| 06:28 | TEttinger | you could try .doStop instead of .stop |
| 06:29 | TEttinger | (I agree with your instincts that it should be called stop) |
| 06:29 | devll | it does. |
| 06:29 | devll | please look at my close-jetty |
| 06:30 | devll | it works |
| 06:30 | devll | IllegalArgumentException No implementation of method: :stop of protocol: #'com.stuartsierra.component/Lifecycle found for class: nil clojure.core/-cache-protocol-fn (core_deftype.clj:555) |
| 06:30 | devll | jetty 9 |
| 06:33 | devll | let me try doStop |
| 06:34 | TEttinger | ohhh |
| 06:34 | TEttinger | it has to do with component/Lifecycle |
| 06:36 | TEttinger | I have no idea how stuartsierra's lib works |
| 06:36 | devll | OK. |
| 06:36 | devll | thanks anyway. |
| 06:36 | devll | I will read the code myself. |
| 06:38 | TEttinger | I'm not sure how defrecord works, tbh |
| 06:39 | TEttinger | ##(doc defrecord) |
| 06:39 | lazybot | ⇒ "Macro ([name [& fields] & opts+specs]); (defrecord name [fields*] options* specs*) Currently there are no options. Each spec consists of a protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args*] body)* D... https://www.refheap.com/98006 |
| 06:42 | devll | changing to doStop gives NPE. |
| 06:43 | TEttinger | interesting, it is null then somewhere |
| 06:44 | TEttinger | oh, and (assoc component :server nil) won't change component |
| 06:44 | devll | but close-jetty works perfectly |
| 06:45 | TEttinger | ,(def component {:server "something"}) |
| 06:45 | clojurebot | #'sandbox/component |
| 06:45 | TEttinger | ,(assoc component :server nil) |
| 06:45 | clojurebot | {:server nil} |
| 06:45 | TEttinger | ,component |
| 06:45 | clojurebot | {:server "something"} |
| 06:45 | devll | I think assoc is different for Component. |
| 06:46 | devll | not this immutable way. |
| 06:47 | TEttinger | what's the type of component, the arg you get called component? |
| 06:47 | TEttinger | (class component) |
| 07:00 | zot | it should be an Httpserver record |
| 07:00 | zot | and the dissoc/assoc at the ends looks correct to me |
| 07:40 | Guest7286 | I have question: I removed core_test.clj and now Leiningen fails to run the other tests. I tried to find a solution, but Google doesn't seem to know how to fix it. Does anyone have an idea how to fix this? |
| 07:48 | Guest7286 | never mind, it was a namespace clash that made it happen. sorry aobut that |
| 07:57 | Eremox | Is it possible to create a circular list without creating a new data structure? |
| 08:00 | schmir | , (take 10 (cycle [1 2 3])) |
| 08:00 | clojurebot | (1 2 3 1 2 ...) |
| 08:01 | schmir | Eremox: does cycle help? |
| 08:02 | Eremox | Think of a list where the second element is the list itself |
| 08:03 | hyPiRion | Eremox: no, cycle is the closest you get |
| 08:03 | hyPiRion | It's effectively the same thing though |
| 08:03 | Eremox | OK thanks anyway. |
| 08:26 | ssideris | Eremox: you could make your own lazy seq and return whatever you like as the next element |
| 08:26 | ssideris | doesn't have to be realized |
| 08:26 | Eremox | Yeah thanks I will try it. |
| 08:45 | sveri | Hi, did someone here do an app where he receives several chunks on the backend from cljs (like with resumable.js)? |
| 08:45 | sveri | I wonder how to handle the data that comes up |
| 09:40 | sveri | Hm, ok, in a different way, I get a org.eclipse.jetty.server.HttpInput in the request. How do I access it's contents or store it on disk? |
| 09:41 | sveri | calling .read on it returns -1 which means that the end is reached |
| 09:43 | llasram` | sveri: Two possibilities off the top of my head: (a) the request has no body content (e.g. is a normal GET); (b) something else in your stack is consuming the entire input |
| 09:44 | sveri | llasram`: ah, I look the second one up, taking out some middlewares, good idea |
| 09:44 | ordnungswidrig | sveri: it's an inputstream, I typically use "slurp" on it. depending on the content-type of course |
| 09:45 | ordnungswidrig | svri: you can dump the complete request with `(prn request)` at some point, that might give you some insight |
| 09:46 | sveri | llasram: ordnungswidrig hm, it still is empty, even when removing my own questionable middleware, still strange. I am using resumable.js which sends get request with some content. at least get requests are all that get out |
| 09:47 | sveri | ordnungswidrig: slurp returns an empty string |
| 09:49 | mpenet` | body in GET is not always supported, it's not clearly defined by the http spec if I recall |
| 09:50 | mpenet` | depending on the server you're using it might just be ignored |
| 09:50 | sveri | mpenet`: Yea, I wonder if I am using it the wrong way |
| 09:50 | mpenet` | probably |
| 09:51 | ordnungswidrig | GET does not support a body in all practical applications |
| 09:51 | ordnungswidrig | I think in HTTP/2 they got that clear |
| 09:52 | mpenet` | yup |
| 09:52 | sveri | kk, the docs also talk about POST requests |
| 09:52 | sveri | weird |
| 09:58 | sveri | ok, thank you, I must be using it wrong, will be looking how to fix this :-) |
| 11:31 | takosuke | hello peoples, I got a quick question if anybody is up for it - |
| 11:31 | Glenjamin | ~ask |
| 11:31 | clojurebot | The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question. |
| 11:32 | takosuke | lol |
| 11:32 | takosuke | understood :) |
| 11:32 | takosuke | i want to have a login-required route in flask proxy to a different app |
| 11:32 | takosuke | wordpress in this case |
| 11:33 | takosuke | the point is to use only one auth system (the one implemented in flask) to give access to the content |
| 11:33 | takosuke | im thinking of doing some proxy magic with nginx but i cant quite fit the pieces together |
| 11:35 | takosuke | something like setting up a virtual host for the wordpress app that can only be accessed internally via localhost:9000 |
| 11:35 | justin_smith | where does clojure fit into this? |
| 11:35 | takosuke | omg |
| 11:35 | takosuke | sorry |
| 11:35 | takosuke | wrong channel!! |
| 11:35 | justin_smith | heh |
| 11:35 | takosuke | lol |
| 11:35 | xemdetia | so as part of the ask to ask protocol |
| 11:35 | xemdetia | do we send him a reset? |
| 11:35 | takosuke | i badly need a reset |
| 12:00 | sritchie | has anyone seen this? CompilerException java.lang.RuntimeException: No reader function for tag +clj, compiling:(taoensso/sente:606:89) |
| 12:00 | sritchie | compiling a file at the REPL |
| 12:00 | sritchie | this happens on my latest Sente upgrade - as far as I know, the cider repl’s not supposed to try and compile raw cljx files |
| 12:02 | sritchie | is it possible to exclude files from a jar dependency? |
| 12:02 | justin_smith | sritchie: well, an easy thing would be to try a regular (non-cider) repl and see if the error is still there |
| 12:02 | sritchie | good call, trying |
| 12:03 | the_frey | If I have a massive lazy-seq and I call partition-all on it, then doseq to call some functions on the partitions I run out of memory |
| 12:03 | the_frey | is that because the previous partitions are kept in memory? |
| 12:03 | the_frey | I thought doseq discarded the head |
| 12:03 | sritchie | the_frey: did you bind the lazy-seq to something? |
| 12:03 | justin_smith | the_frey: do you have a binding somewhere to the beginning of the list directly? |
| 12:03 | sritchie | (def my-seq ...) |
| 12:03 | the_frey | it's in a let binding yeah |
| 12:04 | sritchie | justin_smith: still happens at a normal repl |
| 12:05 | the_frey | (let [foo (partition-all 10000 data-seq)] (doseq [data data-seq] load-into-db data)) |
| 12:05 | justin_smith | sritchie: cool, so it's not a cider problem |
| 12:05 | the_frey | justin_smith ^ is a kinda simplified version of what I'm doing here |
| 12:05 | justin_smith | the_frey: that should not be holding onto the data - unless foo escaped the let block |
| 12:05 | the_frey | is it because it's returning a lazy seq of fully-qualified seqs? |
| 12:05 | justin_smith | (or something using foo escaped the let block) |
| 12:05 | the_frey | sorry |
| 12:05 | justin_smith | doseq returns nil |
| 12:06 | the_frey | (let [foo (partition-all 10000 data-seq)] (doseq [data foo] load-into-db data)) |
| 12:06 | the_frey | ^ is what I meant |
| 12:06 | justin_smith | that let block returns nil, so it will not hold onto foo's head |
| 12:07 | justin_smith | and thus that shouldn't leak |
| 12:07 | the_frey | hmmm |
| 12:07 | the_frey | the weird thing is if I fully qualify this lazy seq, it takes like twenty mins but will eventually churn through in linear time |
| 12:07 | justin_smith | I assume load-into-db isn't holding onto it's args after the db transaction? |
| 12:07 | justin_smith | fully qualify? |
| 12:07 | the_frey | holding onto its args in what way? |
| 12:08 | the_frey | fully realize? |
| 12:08 | justin_smith | OK, that's weird |
| 12:08 | the_frey | sorry, long day, a bit flu-ey |
| 12:08 | sritchie | justin_smith: brutal. gonna try publishing my own version of sente with cljx files excluded. |
| 12:08 | the_frey | yeah this way it stays way lower in CPU usage but still dies after a while, so my guess is a leak |
| 12:09 | justin_smith | the_frey: have you tried profiling? jvisualvm is free, it comes with the jdk, point and click |
| 12:09 | the_frey | good shout |
| 12:10 | the_frey | I will go and have a nose |
| 12:10 | the_frey | cheers! |
| 12:13 | arrdem | Has anyone messed with play-clj? I'm trying to find the path of least resistance to drawing a simple sprite & rotation based GUI |
| 12:14 | xemdetia | justin_smith, I must warn that jvisualvm is sun java only :) |
| 12:14 | xemdetia | or at least doesn't work with the jvm's I've tried |
| 12:15 | justin_smith | xemdetia: jvm or jdk? |
| 12:15 | xemdetia | jvm, I think I tried using it against ibm jre and it failed |
| 12:16 | godd2 | 2acronym4me |
| 12:16 | xemdetia | ibm jre has other fun tracy-profile options though |
| 12:16 | Shayanjm | Hey guys, I'm trying to write a macro that returns a function for a circle given a radius and x/y offsets |
| 12:16 | Shayanjm | here's what I've got: https://gist.github.com/shayanjm/8773123440a7c8cc2258 |
| 12:17 | Shayanjm | my issue is that when I macroexpand-all to inspect, that inner 't' (the argument to the anonymous function i'm trying to generate) ends up becoming <NAMESPACE>/t -- which obviously throws an error when used |
| 12:17 | arrdem | Shayanjm: the inner t needs to be a gensym. try using the token t#. |
| 12:17 | justin_smith | xemdetia: openjdk has a visualvm project, checking whether they include it with their jdk, I thought they did |
| 12:18 | xemdetia | oh I forgot about openjdk |
| 12:18 | xemdetia | It might indeed work there |
| 12:18 | Shayanjm | Excellent thanks a lot arrdem. I've been on python for a while so i've forgotten my clj know-how :( |
| 12:19 | Shayanjm | you still in ATX btw? |
| 12:19 | arrdem | Shayanjm: you remember what -# does in the context of `? yep. |
| 12:19 | arrdem | we never did get coffee :P |
| 12:19 | Shayanjm | I'm pinning that on you ;) |
| 12:19 | arrdem | I'll take it |
| 12:20 | Shayanjm | umm, i can't really articulate what -# does in the context of ` but my best swing is that it generates a symbol to be used within the context of the result of the macro? |
| 12:20 | sritchie | ambrosebs: hey hey |
| 12:20 | sritchie | this is easier than twitter |
| 12:20 | Shayanjm | instead of evaluating immediately, or evaluating upon generation |
| 12:20 | sritchie | ambrosebs: right when I include core.typed I get that error from piggieback (with cljs excluded from core.typed) |
| 12:20 | sritchie | ambrosebs: I’d love to get my team switched from schema to a real type system |
| 12:21 | justin_smith | Shayanjm: it escapes the auto-namespacing of `, while using a gensym to prevent accidental capture of symbols from the place the macro is used |
| 12:21 | arrdem | Shayanjm: in ` context, -# postfixed symbols are named gensyms. It's equivalent to wrapping your ` form with (let [t (gensym "t")] `...) and using ~t instead of t# |
| 12:21 | Shayanjm | ahhh |
| 12:22 | arrdem | Shayanjm: if you want an unqualified, named symbol `~'foo is the raw symbol foo. Handy sometimes if you actually do want closures or named parameters. |
| 12:22 | Shayanjm | Gotcha |
| 12:22 | Shayanjm | arrdem: have you graduated? |
| 12:23 | arrdem | neg. spring next year. |
| 12:23 | Shayanjm | sweet, any solid plans after grad? |
| 12:23 | Shayanjm | or gonna cross that bridge when it comes? |
| 12:24 | arrdem | lolno I'm just trying to get graduated first. bomb that bridge when I get to it. |
| 12:24 | Shayanjm | lolol can respect |
| 12:24 | arrdem | will be at Factual over the summer... so hopefully amalloy et all won't get sick of me :P |
| 12:26 | Shayanjm | sounds like fun |
| 12:29 | arrdem | I sure hope so |
| 12:39 | Kristien | hi |
| 12:41 | justin_smith | hello and welcome to the beautiful world of Clojure programming |
| 12:44 | Kristien | I love this wonderful world already! |
| 12:44 | justin_smith | (inc puredanger) |
| 12:44 | lazybot | ⇒ 33 |
| 12:44 | justin_smith | for that clojure.inspect link on stackoverflow |
| 12:45 | justin_smith | I had no idea! |
| 12:45 | puredanger | :) |
| 12:46 | justin_smith | it's just too bad there isn't a "mutable" version that has a single display, and lets you push things to it from the repl |
| 12:47 | Glenjamin | that exists |
| 12:47 | Glenjamin | i've seen it |
| 12:47 | justin_smith | in some lib? |
| 12:47 | Glenjamin | if i could only remember what it was called |
| 12:47 | arrdem | There is no new code. |
| 12:47 | justin_smith | haha |
| 12:47 | justin_smith | because I don't want to pop a new frame for every request |
| 12:47 | Glenjamin | it's like a fancy logging/tracing thing that sends the forms to another file |
| 12:48 | Glenjamin | s/file/process/ |
| 12:48 | justin_smith | but I could totally use a thing that showed a tree of the most recent request |
| 12:48 | Glenjamin | and has a web interface |
| 12:48 | justin_smith | right, schmetterling does something like this |
| 12:48 | Glenjamin | and let you say "record the next N events and show me" |
| 12:49 | Glenjamin | that's going to really bug me |
| 12:50 | Glenjamin | maybe it's https://github.com/relevance/mycroft |
| 12:51 | Glenjamin | i don't think that's what i was thinking of :s |
| 12:51 | godd2 | Mycroft Holmes? |
| 12:52 | justin_smith | man, those software company names - "relevance" "factual". I guess "voodoo" and "enigma" were already taken. |
| 12:52 | Glenjamin | aha |
| 12:52 | Glenjamin | http://matthiasnehlsen.com/blog/2014/11/14/Inspect/ |
| 12:52 | Glenjamin | that's the one |
| 12:55 | justin_smith | cool |
| 12:55 | justin_smith | (inc Glenjamin) |
| 12:55 | lazybot | ⇒ 15 |
| 12:56 | justin_smith | Glenjamin: that dude's book looks interesting too, I hope he finishes it |
| 12:57 | Glenjamin | there's also a talk https://skillsmatter.com/skillscasts/6031-birdwatch-building-a-system-in-clojure |
| 12:57 | justin_smith | I prefer books myself, but good to know |
| 13:27 | daniel` | im trying to write a friend workflow with multiple challenges/steps, how could/should I share data between steps that the client should never recieve? |
| 13:30 | justin_smith | daniel`: you can use an in-memory ring session |
| 13:30 | justin_smith | all the client gets is a key used on the server side to look up the session |
| 13:31 | daniel` | mhm, right, a random token or something |
| 13:31 | daniel` | i was wondering what to use to safely identify the user between steps |
| 13:31 | justin_smith | daniel`: yeah, it is built into ring's session stuff if you use the in-memory option |
| 13:32 | justin_smith | the user gets a cookie with their session id |
| 13:32 | daniel` | i already have db sessions setup for another worflow |
| 13:32 | daniel` | workflow |
| 13:32 | justin_smith | OK |
| 13:32 | justin_smith | so you could probably leverage that. You may need ssl to ensure the cookie is not snooped / stolen though? |
| 13:33 | justin_smith | or use ring-anti-forgery |
| 13:33 | justin_smith | https://github.com/weavejester/ring-anti-forgery |
| 13:34 | daniel` | thanks, will look into it |
| 13:35 | daniel` | its not a huge concern as the data the server returns back should be encrypted |
| 13:35 | daniel` | and won't be usable to anyone anyway |
| 13:38 | justin_smith | daniel`: depending what is hapening, you would want to look out for people using the cookie to make changes they should't be authorized to make |
| 13:40 | daniel` | yep, definitely justin_smith |
| 14:20 | ambrosebs | get got into gsoc! |
| 14:20 | ambrosebs | *we |
| 14:21 | havenwood | \o/ |
| 14:21 | justin_smith | cool |
| 14:22 | ro_st | only good things happen when you get time to work on OSS. well done, ambrosebs! |
| 14:28 | ajmagnifico | Anyone have any thoughts on this stack trace? http://cl.ly/image/0p162k160o0S |
| 14:29 | agarman | you have recursion that doesn't end |
| 14:29 | justin_smith | ajmagnifico: sounds like a recursive concat bomb |
| 14:29 | ajmagnifico | It fills up 1024 frames in the stack trace, repeating the same pattern over and over again |
| 14:29 | ajmagnifico | I do use concat |
| 14:29 | justin_smith | ajmagnifico: what can happen, is that you can have nested calls to concat, and if they are not forced before a deep nesting, just getting the first item causes too many layers of lazy-seq realization on the stack, and you get a stack overflow |
| 14:30 | justin_smith | this can sometimes be fixed by using lazy-cat |
| 14:30 | justin_smith | or otherwise refactoring so you don't have a huge number of concat calls being realized all at once |
| 14:30 | Scala | [beginner lisp question] I'm trying to convert {:foo "1 1", :bar "2 2"} to [:foo [1 1], [:bar [2 2]], how do I map over a dictionary mapping like this? |
| 14:30 | ajmagnifico | thx justin_smith, I'll check it out! |
| 14:31 | justin_smith | Scala: seq |
| 14:31 | justin_smith | ,(seq {:a 0 :b 1}) |
| 14:31 | clojurebot | ([:b 1] [:a 0]) |
| 14:31 | justin_smith | Scala: also, map already calls seq on its arg |
| 14:31 | justin_smith | so you can just call map on the hash-map and it works |
| 14:31 | agarman | justin_smith: Scala also has a string split happening |
| 14:31 | llasram | And a Long/parseLong |
| 14:31 | justin_smith | OK |
| 14:31 | Scala | I'm not too concerned about that part |
| 14:32 | justin_smith | that's just details :) |
| 14:32 | agarman | yep |
| 14:32 | Scala | so since map will make a 2 element list out of map entries, is there a nice way to have a function expect that but treat it as 2 separate args? |
| 14:32 | agarman | you can just use (map (fn ...) {:foo "1 1" ...}) as well |
| 14:32 | agarman | no need doing seq first |
| 14:33 | llasram | ,(map (fn [[k v]] {:key k, :value v}) {:foo "1 1", :bar "2 2"}) |
| 14:33 | clojurebot | ({:key :bar, :value "2 2"} {:key :foo, :value "1 1"}) |
| 14:33 | llasram | "destructuring" |
| 14:33 | agarman | ,(map (fn [[a b]] [a b]) {:foo "1 1"}) |
| 14:33 | clojurebot | ([:foo "1 1"]) |
| 14:33 | justin_smith | ,(map (fn [[k v]] [k (map #(Long/parseLong %) (clojure.string/split #" " v)) {:foo "1 1" :bar "2 2"}) |
| 14:33 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 14:33 | llasram | heh |
| 14:33 | justin_smith | oops |
| 14:34 | agarman | ,(map (vector %1 %2) {:foo "1 1"}) |
| 14:34 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: %1 in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:34 | agarman | ,(map (vec %1 %2) {:foo "1 1"}) |
| 14:34 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: %1 in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:34 | agarman | ,(map #(vector %1 %2) {:foo "1 1"}) |
| 14:34 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval176/fn--177> |
| 14:34 | Scala | agarman: I think (fn [[a b]]) is what I was looking for |
| 14:34 | agarman | ,(map #(vec %1 %2) {:foo "1 1"}) |
| 14:34 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval204/fn--205> |
| 14:34 | agarman | dang it |
| 14:34 | agarman | nvm |
| 14:35 | justin_smith | ,(map (fn [[k v]] [k (map #(Long/parseLong %) (clojure.string/split #" " v))]) {:foo "1 1" :bar "2 2"}) |
| 14:35 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.util.regex.Pattern> |
| 14:35 | justin_smith | blerg, wrong one :: |
| 14:35 | agarman | yeah, there's a #(... %1 %2) syntax as well |
| 14:35 | justin_smith | ,(map (fn [[k v]] [k (map #(Long/parseLong %) (clojure.string/split v #" "))]) {:foo "1 1" :bar "2 2"}) |
| 14:35 | clojurebot | ([:bar (2 2)] [:foo (1 1)]) |
| 14:35 | justin_smith | there we go! |
| 14:37 | engblom | How is clojure storing a list? Is it keeping a count variable updated or will (count my-list) traverse the list in order to tell the length? |
| 14:37 | justin_smith | ajmagnifico: ##(nth (iterate #(concat nil % []) [1]) 10000) |
| 14:37 | lazybot | java.lang.StackOverflowError |
| 14:38 | justin_smith | ajmagnifico: ##(nth (iterate #(concat nil % []) [1]) 10) |
| 14:38 | lazybot | ⇒ (1) |
| 14:38 | agarman | ,(counted '(1 2 3 4 5)) |
| 14:38 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: counted in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:38 | rhg135 | engblom: for lists it's linear |
| 14:38 | justin_smith | notice the only difference is the number of concat calls that got stacked up |
| 14:38 | agarman | ,(counted? '(1 2 3 4 5)) |
| 14:38 | clojurebot | true |
| 14:38 | rhg135 | for vectors a count is kept |
| 14:38 | engblom | rhg135: Thanks! |
| 14:38 | rhg135 | np |
| 14:39 | agarman | ,(counted? {1 2 3 4}) |
| 14:39 | clojurebot | true |
| 14:39 | agarman | ,(counted? (range 1000)) |
| 14:39 | clojurebot | false |
| 14:39 | justin_smith | ,(counted? (cons 1 nil)) |
| 14:39 | clojurebot | true |
| 14:39 | justin_smith | I had no idea/// |
| 14:40 | engblom | According to what agarman man got the bot to tell, the length of a list seem to be stored |
| 14:40 | engblom | (doc counted?) |
| 14:40 | clojurebot | "([coll]); Returns true if coll implements count in constant time" |
| 14:40 | Scala | agarman: I think (fn [[a b]]) is what I was looking for |
| 14:40 | Scala | whoops |
| 14:40 | agarman | ,(counted? (seq 1 2 3)) |
| 14:40 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/seq--4091> |
| 14:41 | agarman | ,(counted? (seq '(1 2 3))) |
| 14:41 | clojurebot | true |
| 14:41 | justin_smith | ,(counted? (iterate inc 0)) |
| 14:41 | clojurebot | false |
| 14:43 | justin_smith | agarman: there's an inherent race condition between reading the line, and sending it to irc |
| 14:43 | justin_smith | agarman: and we all get to see your retries :) |
| 14:43 | agarman | justin_smith: mostly trying to hit enter before you've answered the question |
| 14:43 | justin_smith | hehe |
| 14:44 | justin_smith | that's another kind of race |
| 14:44 | agarman | it's a race I'm not likely to win |
| 14:44 | agarman | (inc justin_smith) |
| 14:44 | lazybot | ⇒ 201 |
| 14:44 | agarman | (dec agarman) |
| 14:44 | lazybot | You can't adjust your own karma. |
| 14:45 | agarman | justin_smith: keep the throttle to the floor. it appreciated by more than just me. |
| 14:46 | arav93 | Hi! |
| 14:47 | arav93 | And thank god Clojure got in :) |
| 14:47 | agarman | hi arav93 |
| 14:47 | arav93 | Hi agarman |
| 15:29 | maddprof | Hello all - I'm hoping I'm in the right channel, but I'm looking for some help writing a batch file that sets a few environment variables then executes a jscript file |
| 15:30 | justin_smith | maddprof: I don't think clojure is likely to help you with that |
| 15:30 | justin_smith | it's a great language, but not great for batch files |
| 15:30 | maddprof | justin_smith: any recommended channels? I've posted a question on superuser, but being a new member there I'm not really expecting any traction |
| 15:31 | justin_smith | I don't know, maybe if there is a windows related channel? |
| 15:31 | maddprof | okay thanks, back to google I go! |
| 16:22 | Scala | what is the idiomatic way to join strings in a list conditionally. ["a", "b"] -> "a, b" but ["a"] -> "a" |
| 16:23 | justin_smith | Scala: to me that would usually be a sign of some mistake being made |
| 16:23 | amalloy | Scala: that's not really conditional at all, that's just how joining works. see clojure.string/join |
| 16:23 | justin_smith | oh, n/m, amalloy is right, I misread :) |
| 16:23 | Scala | oh, derp |
| 16:23 | justin_smith | ,(clojure.string/join "," ["a"]) |
| 16:23 | clojurebot | "a" |
| 16:24 | justin_smith | ,(clojure.string/join ", " ["a" "b"]) |
| 16:24 | clojurebot | "a, b" |
| 16:24 | justin_smith | (pretend I used ", " the first time too, the result would have been the same) |
| 16:25 | godd2 | He's lying |
| 16:26 | justin_smith | :) |
| 16:26 | justin_smith | ~justin_smith |
| 16:26 | clojurebot | justin_smith sits on a throne of lies |
| 16:27 | SegFaultAX | justin_smith: You smell like beef and cheese, you don't smell like justin_smith! |
| 16:28 | justin_smith | SegFaultAX: how did you know I had beef tacquitos for breakfast! what witchcraft is this! |
| 16:30 | amalloy | justin_smith: you had me worrying it might actually be spelled tacquito |
| 16:31 | justin_smith | oh man... |
| 16:32 | amalloy | which just makes no sense at all in spanish, but who knows what kind of tragedies english has wrought |
| 16:32 | Kristien | tacquito programming is tacit programming in Spanish |
| 16:33 | amalloy | Kristien: eh? |
| 16:38 | crazydiamond | Hi. What's best practice for doing testing in Clojure? Is it better to keep tests (calls to deftest and run-tests) in the same file where functions are or separate one? |
| 16:38 | justin_smith | crazydiamond: run-tests shouldn't be in any of your files - use a tool like "lein test" to find and run all your tests |
| 16:38 | justin_smith | and put tests in their own test namespaces |
| 16:39 | crazydiamond | justin_smith, ok, so, let's say I want to do TDD in vim? |
| 16:39 | justin_smith | you can also call run-tests from the repl if you want to do tdd |
| 16:39 | devll | (sh "rmdir" "*" :dir "resources/ghosts/output") |
| 16:39 | crazydiamond | aha, ok, thanks |
| 16:39 | devll | why "*" does not work? |
| 16:41 | devll | ** why does not "*" take effect? |
| 16:42 | justin_smith | devll: I'm not sure, maybe you explicitly have to tell the shell it spawns to turn globbing on? |
| 16:42 | hiredman | * is a shell glob, it is expand by the shell, sh is, despite its name, not actually executing commands via a shell |
| 16:43 | justin_smith | hiredman: oh, that would explain it. I was looking at the source but had not gotten that deep yet. |
| 16:43 | justin_smith | (inc hiredman) |
| 16:43 | lazybot | ⇒ 73 |
| 16:43 | devll | OK . (inc hiredman) thanks. |
| 16:44 | crazydiamond | is there a vim plugin to auto-pretty-indent Clojure code in current buffer? |
| 16:44 | justin_smith | devll: yeah, this works here: (sh "sh" "-c" "echo *") |
| 16:45 | justin_smith | crazydiamond: yeah, I think there is a vim integration for clj-fmt |
| 16:45 | justin_smith | https://github.com/weavejester/cljfmt |
| 16:47 | crazydiamond | btw, as long as this is an utility https://github.com/weavejester/cljfmt |
| 16:47 | crazydiamond | may I install it globally? |
| 16:47 | justin_smith | crazydiamond: you may want it as a :plugins entry in ~/.lein/profiles.clj |
| 16:48 | justin_smith | crazydiamond: which is exactly what it recommends doing on the readme |
| 16:48 | crazydiamond | yep, and what to run afterwards? lein deps while being in my home dir? |
| 16:48 | justin_smith | no, deps is always implicit |
| 16:48 | devll | thanks . (inc justin_smith) |
| 16:48 | justin_smith | and installs are always per-user |
| 16:49 | justin_smith | so you can just add it to your :plugins then run "lein cljfmt check" or use the vim binding for it or whatever |
| 16:49 | devll | (inc justin_smith) |
| 16:49 | lazybot | ⇒ 202 |
| 16:49 | crazydiamond | aha |
| 16:49 | crazydiamond | cool, thanks! |
| 16:55 | sritchie | ambrosebs: hey |
| 16:55 | sritchie | ambrosebs: around? |
| 17:13 | profil | I am having trouble with referring a macro, I am doing "(ns my-namespace (:require [gloss.core :as g :refer-macros [defcodec]]))" and then I try to use defcodec directly but getting "Unable to resolve symbol". If i do g/defcodec I can access it. Whats wrong? |
| 17:14 | ztellman | profil: as far as I know, :refer-macros is a cljs thing, and Gloss is JVM-only |
| 17:14 | justin_smith | yeah, clj will just ignore the :refer-macros key afaik |
| 17:14 | profil | ahh that makes sense :D |
| 17:15 | profil | so I can just refer a macro as usual then? |
| 17:15 | profil | yes, that worked, thanks guys |
| 17:17 | crazydiamond | btw, when doing TDD in Clojure, how to struggle with constant problems like "there was some (def foo ...), and after I removed it it appears again". I'm doing :%Eval (in vim plugin fireplace) to run tests (actually I often ant to see just output of some command, not perform test) |
| 17:17 | justin_smith | crazydiamond: reloading a namespace does not eliminate defs that are removed from the ns |
| 17:18 | crazydiamond | yep, I realized that. so I probably must remove (ns ) form top of the file |
| 17:18 | justin_smith | that won't help |
| 17:18 | crazydiamond | that a am evaluating |
| 17:18 | crazydiamond | so, I wonder what's correct way |
| 17:19 | justin_smith | crazydiamond: there is a function to remove a var, I am trying to find it (forgot the name) |
| 17:19 | crazydiamond | but, isn't there some more general approach? |
| 17:20 | crazydiamond | like forgetting about what was there just some time before |
| 17:20 | crazydiamond | I mean, reloading |
| 17:20 | justin_smith | clojure.tools.namespace has some stuff for this |
| 17:20 | justin_smith | but no, loading the file does not delete definitions |
| 17:20 | crazydiamond | I am using this |
| 17:20 | crazydiamond | (require 'clojure.tools.namespace.repl) |
| 17:20 | crazydiamond | (clojure.tools.namespace.repl/refresh) |
| 17:21 | crazydiamond | in the end it would turn so that I would need re-launch repl every time |
| 17:21 | crazydiamond | which is incorrect and just ugly |
| 17:22 | justin_smith | crazydiamond: ns-unmap will delete a var from a namespace |
| 17:22 | crazydiamond | thanks, but provided some name... |
| 17:23 | justin_smith | ns-publics will give you all vars in a given namespace |
| 17:23 | justin_smith | (well, all that are visible outside that namespace) |
| 17:24 | crazydiamond | but... aren't there just some best-practices? |
| 17:25 | justin_smith | running lein check or lein eastwood will tell you when you have code that reflects definitions that no longer exist |
| 17:26 | justin_smith | eastwood is generally helpful, in other ways as well |
| 17:30 | crazydiamond | however, doing :%Eval in vim... that should be equivalent of just throwing that bunch of code into REPL? |
| 17:31 | justin_smith | right |
| 17:31 | justin_smith | within the apropriate namespace context |
| 17:33 | Scala | I'm checking program args when running the program. If they fail my check I want to print a line and exit. An if statement only lets me run one action though, and putting both actions in a function with no args doesn't run. What's the proper way to do this? |
| 17:33 | justin_smith | do |
| 17:34 | justin_smith | (do (println "message") (System/exit 42)) |
| 17:34 | justin_smith | also, this may be a good place to use when (which like functions contains an implicit do) |
| 17:35 | justin_smith | (when we-outta-here-homies (println "bye") (System/exit 42)) |
| 17:36 | justin_smith | when is if with a do block and only one branch |
| 17:44 | Geeky_Vin | Hello Fellow Clojurers! I have a simple doubt could some help me. I have a string, "{\"result\" : \"some value\"}" now How do I convert it to just {result: some value} |
| 17:45 | justin_smith | Geeky_Vin: you can use cheshire or clojure.data.json |
| 17:46 | justin_smith | wait, that would give you {:result "some value"} |
| 17:46 | justin_smith | {result: some value} is not a valid clojure form |
| 17:49 | Geeky_Vin | @justin_smith yeah but not if you set the third value as true ;) |
| 17:50 | havenwood | Geeky_Vin: Deserialize the JSON? |
| 17:50 | Geeky_Vin | oh wait I see what you mean |
| 17:50 | Geeky_Vin | but still thats enough for me! |
| 17:50 | havenwood | (json/read-str "{\"result\" : \"some value\"}") #=> {"result" "some value"} |
| 17:50 | Geeky_Vin | @havenwood yes Haven |
| 17:51 | Geeky_Vin | @havenwood but I need to preserve the map value |
| 17:51 | Geeky_Vin | in map: form or :map value |
| 17:51 | Geeky_Vin | I mean key sry |
| 17:52 | Geeky_Vin | i.e key : value or :key value |
| 17:53 | havenwood | (json/read-str "{\"result\" : \"some value\"}" :key-fn keyword) #=> {:result "some value"} |
| 17:53 | havenwood | Geeky_Vin: Like that ^ or am I still not getting it? |
| 17:55 | Geeky_Vin | @havenwood oh yeah thats better its equivalent to parse-string in cheshire btw |
| 17:55 | havenwood | Geeky_Vin: Like the second example here?: https://github.com/dakrone/cheshire#decoding |
| 17:58 | Geeky_Vin | @havenwood yeah. |
| 18:01 | nicferrier | ,ping |
| 18:01 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ping in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 18:04 | justin_smith | $ping nicferrier |
| 18:05 | nicferrier | justin_smith: :-) - I thought I was in #emacs. |
| 18:05 | justin_smith | hmm, I wonder if that plugin broke |
| 18:05 | justin_smith | $ping |
| 18:05 | lazybot | justin_smith: Ping completed in 0 seconds. |
| 18:06 | justin_smith | $ping example.com |
| 18:06 | lazybot | justin_smith: FAILURE! |
| 18:12 | amalloy | justin_smith: lazybot's website-pinging feature never made much sense to me |
| 18:15 | Glenjamin | $ping isup.me |
| 18:15 | lazybot | Glenjamin: Ping completed in 0 seconds. |
| 18:16 | crazydiamond | Is there way to create new namespace for which result of ns-refers wouldn't be empty and switch to it? |
| 18:16 | justin_smith | crazydiamond: ns |
| 18:16 | bucketh3ad | I've got a doseq with two side-effect functions that operate over a sequence. What is the best way to change (doseq [s my-seq] (func1 s) (func2 s)) so that it runs ALL func1's first then ALL func2's, rather than in pairs for each element of the sequence? |
| 18:16 | justin_smith | or you can manually call clojure.core/refer-clojure within that ns |
| 18:16 | amalloy | justin_smith: you know about lazybot's actual useful pinging feature though, right? |
| 18:16 | crazydiamond | justin_smith, ok, but given some name? |
| 18:17 | amalloy | where you write "amalloy: ping", and lazybot will PM you when he notices me talking in any channel |
| 18:17 | justin_smith | crazydiamond: I guess you could use create-ns and refer-clojure, but why do you need to create namespaces at runtime anyway? |
| 18:17 | crazydiamond | justin_smith, I want to create ns with random name each time I'm doing :%Eval. that crazy hack |
| 18:17 | amalloy | bucketh3ad: you write it as two doseqs |
| 18:18 | amalloy | you want to walk over the seq twice, not walk over it once doing two things, so that's what you have to write |
| 18:18 | crazydiamond | justin_smith, 'cause Clojure isn't about updating and deletion. it's about creating new :D |
| 18:19 | bucketh3ad | amalloy: Thanks! That seemed like the right path, but I wasn't sure if there was a more idiomatic method. |
| 18:21 | amalloy | i mean, you can do some silly business if you want, but it's silly. like just for fun: ((reduce (fn [f s] (fn [] (do (thing1 s) (f) (thing2 s)))) (fn []) myseq)) |
| 18:22 | amalloy | which is not quite right since it does like (f1 c) (f1 b) (f1 a) (f2 a) (f2 b) (f2 c) |
| 18:23 | bucketh3ad | Yeah, that is pretty silly |
| 18:32 | crazydiamond | (eval `(ns ~(gensym))) |
| 18:33 | crazydiamond | let the testing begin |
| 18:33 | akkad | is there away to avoid duplicate function names? some dev overwrote my function without knowing it. |
| 18:33 | akkad | no errors popped up anywhere |
| 18:34 | Glenjamin | akkad: namespaces? |
| 18:34 | akkad | this happens to be the same namespace |
| 18:34 | Glenjamin | smaller namespaces? :p |
| 18:34 | akkad | just looking for compiler options to assert on this like CL |
| 18:35 | Glenjamin | https://github.com/jonase/eastwood might have it |
| 18:35 | Glenjamin | aha, here we go |
| 18:35 | Glenjamin | https://github.com/jonase/eastwood#redefd-vars |
| 18:36 | akkad | perfect thanks |
| 19:01 | Bronsa | ,(. Double -POSITIVE_INFINITY) |
| 19:01 | clojurebot | Infinity |
| 19:01 | Bronsa | ,(.-POSITIVE_INFINITY Double) |
| 19:01 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: POSITIVE_INFINITY for class java.lang.Class> |
| 19:01 | Bronsa | :| |
| 19:02 | Glenjamin | doesn't .- only work on instances? |
| 19:02 | amalloy | well, evidently that is so |
| 19:02 | Glenjamin | weird that (. class -field) works tho |
| 19:03 | Bronsa | i'm not sure that the failing case is intentional |
| 19:03 | Glenjamin | ,Double/POSITIVE_INFINITY ; is the recommended way though? |
| 19:03 | clojurebot | Infinity |
| 19:04 | amalloy | yes |
| 19:04 | Bronsa | Glenjamin: sure but that should just be sugar over . |
| 19:05 | amalloy | Bronsa: it is |
| 19:06 | amalloy | it's sugar over (. Double POSITIVE_INFINITY), with no - |
| 19:09 | Bronsa | amalloy: I cannot read anywhere that the .- field access syntax should not work for static fields and should only work for instance fields |
| 19:09 | Bronsa | so I think it should be reasonable to expect (.-POSITIVE_INFINTY Double) to work |
| 19:11 | Bronsa | wrt (. foo -bar) behaving like (.-bar foo), no idea if that's by design but it's definitely supported by both clj and cljs and cljs explicitely uses it |
| 19:11 | Bronsa | so I just always assumed it was intentional |
| 19:12 | amalloy | i imagine in cljs both forms work, right? |
| 19:12 | Bronsa | yeah, in clj too |
| 19:12 | Bronsa | ,(deftype x [y]) |
| 19:12 | clojurebot | sandbox.x |
| 19:12 | Bronsa | ,(.-y (x. 1) |
| 19:12 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 19:12 | Bronsa | ,(.-y (x. 1)) |
| 19:12 | clojurebot | 1 |
| 19:13 | Bronsa | ,(. (x. 1) -y) |
| 19:13 | clojurebot | 1 |
| 19:15 | blake_ | OK, so, I'm catching exception in some code, the idea being to catch all the exceptions and return them as a seq. |
| 19:15 | blake_ | But what happens instead is I'm eating them. Or at least some of them. java.lang.NullPointerException in particular. |
| 19:16 | blake_ | It actually looks like other exceptions are returned. Since I'm not discriminating, I don't see how it can happen. |
| 19:17 | blake_ | I have some code https://www.refheap.com/98037 but I'm not sure how instructive it is. |
| 19:17 | zengy | exit |
| 19:18 | blake_ | Maybe it's eating them all and the code just doesn't build the error list I think it's building. (I make a vector out of the exceptions and return that.) |
| 19:30 | blake_ | Eh. Maybe just rewrite the code so it's easier to debug. =/ |
| 19:32 | justin_smith | blake_: ##(key nil) |
| 19:32 | lazybot | java.lang.NullPointerException |
| 19:32 | justin_smith | blake_: via that specific circumstance (which I think could absolutely happen), you get an exception that breaks out of your catch block |
| 19:32 | justin_smith | and does not get added to the vector of caught exceptions |
| 19:34 | justin_smith | blake_: another factor here is ##(dorun (map inc (range 1000))) |
| 19:34 | lazybot | ⇒ nil |
| 19:34 | blake_ | justin_smith: Interesting. It shouldn't be possible here but that's a good sign that I wouldn't be looking for it. |
| 19:34 | justin_smith | because dorun returns nil, you will never see the results of that keep function |
| 19:35 | blake_ | justin_smith: OK, did the dorun....crap... |
| 19:35 | justin_smith | including the vectors created by catch |
| 19:35 | blake_ | Well, that explains THAT. |
| 19:35 | justin_smith | you probably want doall |
| 19:35 | blake_ | (inc justin_smith) |
| 19:35 | lazybot | ⇒ 203 |
| 19:35 | blake_ | Holy crap! I missed your bicentennial! |
| 19:35 | justin_smith | haha |
| 19:36 | blake_ | I had cake planned and firecrackers... |
| 19:36 | patchwork | blake_: It was quite an event, we were wondering where you were |
| 19:37 | blake_ | Debugging! |
| 19:37 | patchwork | I tried to save you some cake but... you know these monsters |
| 19:39 | blake_ | I'll set the building on fire. |
| 19:45 | blake_ | ##(key nil) |
| 19:45 | lazybot | java.lang.NullPointerException |
| 21:22 | emaczen | What is wrong with this multimethod form? |
| 21:23 | emaczen | (defmulti pushable? :Pile :Pile) |
| 21:23 | justin_smith | why do you list the dispatch twice? |
| 21:23 | emaczen | I want to dispatch on two "piles" |
| 21:23 | justin_smith | that's not how defmulti works |
| 21:24 | justin_smith | (doc defmulti) |
| 21:24 | clojurebot | "([name docstring? attr-map? dispatch-fn & ...]); Creates a new multimethod with the associated dispatch function. The docstring and attr-map are optional. Options are key-value pairs and may be one of: :default The default dispatch value, defaults to :default :hierarchy The value used for hierarchical dispatch (e.g. ::square is-a ::shape) Hierarchies are type-like relationships that do not depend upon type inheritance. By default Clo |
| 21:24 | emaczen | Okay, so I have to make a different dispatch function |
| 21:24 | justin_smith | what do you expect to dispatch on? |
| 21:24 | justin_smith | two args? |
| 21:25 | emaczen | Yes |
| 21:25 | justin_smith | (defmulti pushable? (fn [a b] [(:Pile a) (:Pile b)])) maybe |
| 21:25 | justin_smith | that would treat each order pair of :Pile as a separate dispatch |
| 21:26 | emaczen | justin_smith, thanks that is what I am looking for |
| 21:28 | justin_smith | you could also make the dispatch function varargs if you wanted other arities to be acceptable |
| 21:36 | emaczen | what is the function for pushing/appending an element to a collection? |
| 21:39 | justin_smith | emaczen: push (for vectors) |
| 21:39 | TEttinger | (doc conj) |
| 21:39 | justin_smith | no such function for lists |
| 21:39 | clojurebot | "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type." |
| 21:39 | amalloy | justin_smith: ... |
| 21:39 | amalloy | conj, not push' |
| 21:39 | justin_smith | conj |
| 21:39 | justin_smith | that was a weird brain fart... |
| 21:39 | justin_smith | sorry |
| 21:39 | TEttinger | haha |
| 21:40 | justin_smith | ~justin_smith |
| 21:40 | clojurebot | ☃ |
| 21:40 | amalloy | *chuckle* |
| 21:40 | TEttinger | ,(def ☃ conj) |
| 21:40 | clojurebot | #'sandbox/☃ |
| 21:40 | TEttinger | ,(☃ [1 2 3] 4) |
| 21:40 | clojurebot | [1 2 3 4] |
| 21:40 | amalloy | ~amalloy |
| 21:40 | clojurebot | amalloy is nuts for juxt |
| 21:41 | TEttinger | clojurebot: TEttinger |is| putting BOMs in all your strings while you sleep |
| 21:41 | clojurebot | Ok. |
| 21:43 | emaczen | so conj for vectors but nothing for lists? |
| 21:43 | TEttinger | conj for vectors at the end, conj for lists at the start |
| 21:43 | amalloy | emacsnw: conj adds to a collection in "the natural place", which is different for each kind of collection |
| 21:43 | amalloy | for vectors, it's at the end |
| 21:43 | TEttinger | if you want to attach to the end of a list, that's the worst case for lists, but you can use ##(concat '(1 2 3) [4]) |
| 21:43 | lazybot | ⇒ (1 2 3 4) |
| 21:44 | TEttinger | concat appends sequences |
| 21:44 | TEttinger | which includes lists and vectors and even maps |
| 21:44 | justin_smith | and you can fake something similar with into for prepending on a vector (once again, worst case) |
| 21:45 | justin_smith | ,(concat "hello" "world") |
| 21:45 | clojurebot | (\h \e \l \l \o ...) |
| 21:45 | justin_smith | :P |
| 21:45 | TEttinger | ##(concat '(1 2 3) {:☃ 4}) |
| 21:45 | lazybot | ⇒ (1 2 3 [:☃ 4]) |
| 21:45 | TEttinger | ##(concat '(1 2 3) {:☃ 4 :☃☃☃ 10}) |
| 21:45 | lazybot | ⇒ (1 2 3 [:☃☃☃ 10] [:☃ 4]) |
| 21:46 | TEttinger | note how maps aren't ordered and get split into key-value pairs when treated as a seq |
| 21:51 | emaczen | what is pop! |
| 21:52 | justin_smith | it's like pop, but for transients |
| 21:52 | justin_smith | or as we like to call it, hobo soda |
| 21:52 | emaczen | You beat me to the next question -- what are transients? |
| 21:52 | justin_smith | optimized data structures for updating, if you don't need to access the older values |
| 21:53 | justin_smith | when you are done punching them you can turn them into normal persistent data structures with persistent! |
| 21:53 | emaczen | Is there anything like (push (pop l1) l2) |
| 21:54 | justin_smith | well, it would be conj or into |
| 21:54 | justin_smith | not push |
| 21:54 | TEttinger | so, you wouldn't change the value of l1 there because lists are immutable |
| 21:55 | emaczen | What can I do to get this functionality? |
| 21:55 | TEttinger | ,(conj '(2 3) (head '(1 2 3))) |
| 21:55 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: head in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:55 | TEttinger | ,(conj '(2 3) (first '(1 2 3))) |
| 21:55 | clojurebot | (1 2 3) |
| 21:55 | justin_smith | TEttinger: peek works on lists |
| 21:55 | amalloy | justin_smith: but not seqs in general, sadly |
| 21:55 | justin_smith | right |
| 21:56 | amalloy | it's one of the few reasons list? isn't totally useless |
| 22:00 | justin_smith | ,(map #(instance clojure.lang.IPersitentStack %) [[] () (iterate inc 0) (range) {}]) |
| 22:00 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: instance in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 22:00 | justin_smith | oops |
| 22:00 | justin_smith | ,(map #(instance? clojure.lang.IPersitentStack %) [[] () (iterate inc 0) (range) {}]) |
| 22:00 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: clojure.lang.IPersitentStack, compiling:(NO_SOURCE_PATH:0:0)> |
| 22:00 | justin_smith | ,(map #(instance? clojure.lang.IPersistentStack %) [[] () (iterate inc 0) (range) {}]) |
| 22:00 | clojurebot | (true true false false false) |
| 22:18 | emaczen | why can't I pop a lazySeq? |
| 22:18 | emaczen | What can I do to a lazySeq? |
| 22:20 | TimMc | emaczen: "rest" gives you the lazy seq minus the head, and if that's not pop, I don't know what is |
| 22:21 | emaczen | TimMc: THanks |
| 22:21 | TEttinger | if you want one element, first or nth, if you want a different lazyseq, rest |
| 22:21 | emaczen | (swap! state update-in :deck rest) |
| 22:21 | emaczen | UnsupportedOperationException nth not supported on this type: Keyword clojure.lang.RT.nthFrom (RT.java:857) |
| 22:21 | TimMc | There's also "next", but that's only if you want an empty result to be expressed as nil, not (). |
| 22:21 | amalloy | [:deck] |
| 22:21 | emaczen | Here (:deck @state) is a lazySeq |
| 22:22 | emaczen | I'm not sure why I can't use rest in this context |
| 22:22 | amalloy | emaczen: [:deck], not :deck |
| 22:22 | amalloy | it's entirely unrelated to lazy seqs, you are using update-in wrong |
| 22:23 | TEttinger | update-in takes a vector of things to go "in" to |
| 22:23 | emaczen | why do I have to use the []? |
| 22:23 | emaczen | Okay, I see |
| 22:23 | amalloy | &(doc update-in) |
| 22:23 | lazybot | ⇒ "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created." |
| 22:23 | emaczen | Thanks TEttinger |
| 22:23 | TEttinger | np! |
| 22:23 | emaczen | I'm still getting used to the documentation... |
| 22:24 | amalloy | i think clojure 1.7 is going to include an update function, which would behave like you imagined update-in does |
| 22:24 | amalloy | but i haven't been paying attention to that plan for a while |
| 22:28 | ob_ | learned about the first thread macro (`->) tonight and it made me happy :) |
| 22:28 | ob_ | thread first rather lol |
| 22:30 | TEttinger | it's a good one! |
| 22:30 | ob_ | i can't believe ive been more than one tutorial deep without learning about it |
| 22:31 | ob_ | "Hey world, clojure is like hacking on linux. See, we have pipes in the form of arrows!" |
| 22:32 | emaczen | how many functions warrants a thread first ? |
| 22:32 | gfredericks | two? |
| 22:32 | raspasov | ob_: also take a look at https://clojuredocs.org/clojure.core/some-%3E , it can be useful in some cases |
| 22:32 | justin_smith | 3 |
| 22:32 | gfredericks | I'll sometimes use cond-> and some-> with just one |
| 22:32 | emaczen | is there a general consensus? |
| 22:32 | amalloy | that's the wrong question to ask |
| 22:33 | amalloy | there's not some "cost" to having nested parentheses that -> alleviates, and above a certain level you need -> to survive. you use -> whenever that lets you rearrange your code into an order that's more readable |
| 22:34 | TEttinger | I just use (((((((((((((((((()))))))))))))))))))) |
| 22:34 | ob_ | -> makes reading clojure to a newbie like me totally sane now |
| 22:34 | ob_ | -> is clojure's secret weapon and it doesnt even know it |
| 22:34 | TEttinger | heh, it's true |
| 22:36 | raspasov | but the BEST jedis, they only code in nested (). why? because they can see the future :) |
| 22:37 | amalloy | huh? |
| 22:37 | raspasov | lol I'm kidding |
| 22:37 | raspasov | because if you don't use -> the code is backward, i.e. you need to be able to see "forward" in time to understand it lol |
| 22:38 | amalloy | i don't get the "code is backward" argument. we talk that way in english all the time. verb the noun. verb and verb the adjective noun |
| 22:39 | raspasov | maybe "inside out? |
| 22:39 | amalloy | is "drive the car" inside out? |
| 22:39 | justin_smith | amalloy: but in reverse application order, where the last verb is the first applied? |
| 22:39 | amalloy | i love -> at least as much as the next guy, but so many of the arguments for using it don't make any sense |
| 22:40 | justin_smith | I sleep after I walk home after I go out with some friends after I work after I get up and have coffee |
| 22:40 | raspasov | haha |
| 22:40 | justin_smith | that's how outside in can read |
| 22:41 | ob_ | (z(y(x))) vs (-> x y z) |
| 22:41 | ob_ | pretty damn easy call |
| 22:41 | ob_ | for the uninitiated at least |
| 22:41 | raspasov | http://www.yodaspeak.co.uk/index.php |
| 22:43 | ob_ | The #1 complaint i see on every thread about clojure ever is "omg parens". Only today did I see a comment about thread first macro halfway down the page. |
| 22:43 | raspasov | ob_: the correct macroexpand for this case would be (z (y x)), but I totally agree with you |
| 22:44 | raspasov | (macroexpand-1 '(-> x y z)) |
| 22:46 | puredanger | I think -> is great when there is some consistency to the results flowing through the forms (sequences, collections, etc) |
| 22:46 | puredanger | I'm less a fan when the kind of thing being threaded changes in every line |
| 22:46 | puredanger | although occasionally I see it used to good effect |
| 22:46 | justin_smith | if it has an assembly-line like logic to it |
| 22:47 | raspasov | puredanger: totally agree, I can't count how many times I've done this and then you have to "deconstruct" your code to actually debug/undestand what's going on lol |
| 22:47 | justin_smith | my two best use cases are successive transformations that keep the same basic structure, or nested lookup (when get-in just doesn't suffice) |
| 22:47 | puredanger | yes, exactly |
| 22:47 | ob_ | I don't know where -> doesn't make sense to use, but as a PR move to get people interested in clojure, it's amazing imo. It copmletely disarms the "omg parens" crowd |
| 22:47 | justin_smith | ob_: yeah, less parens than java |
| 22:48 | puredanger | objection to parens is, as we know, silly. but it's also real. |
| 22:48 | ob_ | then again do you want people in the community that will ignore all the goodness bc of parens? |
| 22:48 | ob_ | i think the benefits outweigh tho. if nothing else, you destroy the #1 barrier to entry |
| 22:48 | puredanger | I don't want to think that way |
| 22:49 | raspasov | we should just fork Clojure and make it like Python, that will solve all of the world's problems |
| 22:49 | ob_ | yea me either im not into that "pain is good" stuff |
| 22:49 | justin_smith | ob_: yeah, actually my first response to "omg parens" is usually "they are a cost of entry, and it's worth it" - if someone still can't handle the parens, that's their loss |
| 22:49 | puredanger | I want to find ways to have people put that reactive fear aside long enough to notice everything else |
| 22:49 | justin_smith | raspasov: at that point you just have ml without the static typing |
| 22:49 | ob_ | show them parens and say "if this freaks you out, you can use -> this way:" |
| 22:49 | ob_ | parens first, -> second |
| 22:50 | raspasov | justin_smith: and without the JVM? |
| 22:50 | locks | can I compile a clojure library into a jar and use it from Java in Android? |
| 22:51 | justin_smith | raspasov: well, who says an ml can't compile to the jvm, I'm just saying that's what the language you end up with would effectively be (once you have immutability, and indentation for nesting) |
| 22:51 | amalloy | ob_: -> doesn't even reduce the number of parens except in the absolute least interesting case |
| 22:51 | justin_smith | amalloy: it reduces the depth of them though |
| 22:51 | amalloy | (-> foo (f x) (g y) (h z)) vs (h (g (f foo x) y) z) |
| 22:52 | locks | -> is bad? D: |
| 22:52 | amalloy | that's clearly better-written with ->, but not because of number of parens or depth of anything |
| 22:52 | amalloy | it's because the extra arguments pertaining to h (here, z) are next to h instead of on the opposite side of the expression |
| 22:52 | ob_ | the mental strain of going inside out is significant for a newbie |
| 22:52 | ob_ | like myself |
| 22:52 | ob_ | although at day 7 im getting the hang of it |
| 22:52 | raspasov | amalloy: in nested maps it's nice like (-> deep-nested-map :lvl-1 :lv-2) |
| 22:52 | ob_ | but -> as "linux piping" is a freaking revelation |
| 22:53 | amalloy | raspasov: that should be get-in anyway |
| 22:53 | raspasov | yea that's also possible |
| 22:57 | ob_ | is there really much interop with java in real world clojure |
| 22:58 | ob_ | it almost always reads as a half-hearted benefit rather than something ppl actually do |
| 22:58 | raspasov | ob_: depends on what you're doing, if you need an existing java library that does not have a read clojure wrapper, then yes |
| 22:58 | justin_smith | ob_: I use it plenty |
| 22:58 | justin_smith | ob_: it comes up more when you need a lib for a specific pragmatic thing |
| 22:58 | raspasov | or if you need to use classes like ByteBuffer or other lower-level Java utils |
| 22:58 | justin_smith | it's often easier to just use the java lib for it |
| 22:59 | ob_ | oh ok |
| 22:59 | justin_smith | also, IO tends to be very interop-heavy, beyond the super-basics |
| 23:00 | justin_smith | ob_: for abstract and algorithmic stuff outside a tight loop, yeah, you won't see interop. But for specific utilities or places where you need performance interop will pay off. |
| 23:01 | amalloy | it's also easier to work in a mixed team of clojure programmers and infidels if you can just say "okay, we'll write up an interface, and i'll give you an object that implements that interface" |
| 23:01 | ob_ | lmao infidels |
| 23:02 | ob_ | im guessing clojure programmers are java experts first |
| 23:02 | amalloy | some of them |
| 23:04 | justin_smith | ob_: you should see what he does with apostates |
| 23:04 | justin_smith | it isn't pretty |
| 23:04 | ob_ | #isis? |
| 23:04 | justin_smith | ob_: I learned java after clojure |
| 23:05 | ob_ | my dayjob is sql+asp.net mvc |
| 23:05 | ob_ | but i sneak in some clojure reading |
| 23:05 | justin_smith | ob_: have you checked out clojure-clr? |
| 23:05 | ob_ | ive heard about it |
| 23:05 | justin_smith | it's not as mature, but it has the advantage of using an ecosystem you know better |
| 23:06 | ob_ | im not heavily invested in clr personally |
| 23:07 | ob_ | justin_smith, do you use clojure at work? |
| 23:08 | justin_smith | ob_: yeah, I do contract work, back end for web sites in clojure |
| 23:09 | ob_ | cool |
| 23:14 | justin_smith | is there a name for that thing Microsoft does where they give a super generic name to software? "windows" "sql server" "mvc" |
| 23:16 | ob_ | a marketing term? |
| 23:17 | justin_smith | it's like, attempting to capture the generic term / concept so people will think it implies their version maybe? |
| 23:19 | ob_ | sounds like branding |
| 23:19 | ob_ | the windows brand, sql brand, etc |
| 23:19 | ob_ | sql server rather |
| 23:19 | justin_smith | right |
| 23:20 | justin_smith | it's like the reverse of the kleenex effect - instead of their own brand becoming generic, the generic thing becomes their brand |
| 23:21 | ob_ | interesting |
| 23:22 | ob_ | but i dont know if ms advertises Windows. Don't they always through version numbers to imply you need to upgrade to the new version? |
| 23:23 | ob_ | *Don't they include version numbers |
| 23:24 | justin_smith | yeah |
| 23:25 | ob_ | funny how apple went with OS X which sounds like some mainframe |
| 23:25 | ob_ | while MS went with something kinda creative with Windows |
| 23:25 | ob_ | as far as names go |