2014-10-31
| 00:00 | TimMc | I may have found it by searching for "clojure jobs", not really sure. |
| 00:05 | cfleming | In my macroexpanded code, I'm occasionally seeing vars like G__1234 - does anyone know when the compiler inserts those? |
| 00:06 | cfleming | I've looked at all the uses of RT.nextID() and I can't figure it out. |
| 00:06 | justin_smith | ,(gensym) |
| 00:06 | clojurebot | G__27 |
| 00:06 | cfleming | Aha, thanks. |
| 00:06 | cfleming | Shows how many macros I write. |
| 00:06 | justin_smith | cfleming: they are in the reader for ` when you name something binding# |
| 00:07 | justin_smith | ,`(let [foo# 1] foo#) |
| 00:07 | clojurebot | (clojure.core/let [foo__50__auto__ 1] foo__50__auto__) |
| 00:07 | cfleming | justin_smith: Those are named <name>__1234__auto__, right? |
| 00:07 | justin_smith | ahh, right |
| 00:07 | justin_smith | so the others are manual genzyms |
| 00:07 | justin_smith | *gensyms |
| 00:07 | cfleming | justin_smith: The implicit parameters from a #() are p<num>__1234# |
| 00:08 | justin_smith | ,'#(%) |
| 00:08 | clojurebot | (fn* [p1__75#] (p1__75#)) |
| 00:08 | justin_smith | yeah |
| 00:08 | cfleming | Ok, makes sense - those must be named in clojure.core - I'll take a look. |
| 00:08 | justin_smith | ,(gensym "foo") |
| 00:08 | clojurebot | foo102 |
| 00:09 | cfleming | Ew |
| 00:09 | cfleming | So that one sucks |
| 00:09 | justin_smith | I think it is fairly rare... |
| 00:09 | cfleming | All this is for detecting the changed region in the macroexpander I'm working on. |
| 00:10 | justin_smith | ahh, right, of course |
| 00:11 | cfleming | Some of these are stable across expansions, but some of them are generated every time (G__1234 and pn__1234#) |
| 00:11 | cfleming | I guess I'll have to check whether two syms start with the same string but are suffixed with some different number for the named gensyms. |
| 00:12 | justin_smith | cfleming: what about a placeholder for the number part? |
| 00:12 | justin_smith | yeah |
| 00:12 | justin_smith | and not strictly a suffic, thanks to # being there sometimes of course |
| 00:13 | cfleming | Yeah, I'm planning to shorten them all to things like name<n># for auto-gensyms, p<n># for the parameters and so on, I guess <name># for named gensyms and perhaps G<n># for the plain gensym case. |
| 00:14 | cfleming | Fortunately there's only a couple of patterns. |
| 00:16 | cfleming | Thanks! |
| 00:40 | razum2um | from clojure survey'14 I get to know, that people would like to see "feature experessions" in the language. the idea initially comes from cljx and reminds me on c-ifdef's. i didn't write any cljs yet, but i ask you: is it really needed? I thought, that business logic should be ideally platform independent, why it won't get solved by proper "interface" for functions which deal with host-related things? |
| 00:44 | justin_smith | razum2um: in practice you can reduce the complexity of the codebase by allowing certain expressions to be swapped out based on the backend |
| 00:44 | justin_smith | razum2um: the advantage over C macros is that they are syntax aware, so it's much harder to get the bizzarre results that a bad C macro could give you |
| 00:45 | razum2um | justin_smith: is it really needed only as "syntactic sugar"? |
| 00:45 | razum2um | only to reduce file count? |
| 00:46 | justin_smith | razum2um: I don't know about calling it sugar. Each ns where you can use a feature expression means at least 2 files you don't need. Also, it's more straightforward to read and understand the code when key parts of it aren't split into separate files for backend rather than conceptual organization reasons |
| 00:48 | justin_smith | separation of concerns can simplify things, but when you are splitting things based on impl but sharing others, that can easily be fragmentation of the design rather than simplification. |
| 00:49 | mindbender1 | is there a function I can use to output the bit representation of a number in 1s and 0s? |
| 00:49 | justin_smith | mindbender1: I think there is something in cl-format that can do that |
| 00:49 | razum2um | justin_smith: hm, this reminds me on nodejs and meteorjs. people are trying to merge codebases and finally they end up with "is_this_a_server_or_client" functions. I still think, that only some business logic should be shared and it could and must be written platform independent, or am I an idealist? |
| 00:50 | justin_smith | ,(require '[clojure.pprint :as pprint]) |
| 00:50 | clojurebot | nil |
| 00:50 | justin_smith | ,(pprint/cl-format "~1r" 88) |
| 00:50 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 00:51 | justin_smith | ,(pprint/cl-format nil "~1r" 88) |
| 00:51 | clojurebot | eval service is offline |
| 00:52 | justin_smith | razum2um: tangent - when using the term "business logic" - what is the distinction, what part of the code is not business logic? |
| 00:54 | mindbender1 | justin_smith: I'm trying to read up the docs |
| 00:54 | justin_smith | razum2um: what happens is that you can have, for example, a common data structure between clj and cljs, and want to be able to do the same operations, but you have a small number of operations that need to be implemented differently. being able to describe those differences (if they are very small in number) inline rather than through two more namespaces, can make everything much simpler. |
| 00:54 | razum2um | hm, say "valid user should have name and email" - (defn valid_user? [u] (every? some? ((juxt :email :name) u)))) |
| 00:55 | mindbender1 | justin_smith: see http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/clm/node199.html |
| 00:55 | justin_smith | ,(pprint/cl-format nil "~b" 88) ; mindbender1 |
| 00:55 | clojurebot | "1011000" |
| 00:55 | mindbender1 | ok |
| 00:55 | justin_smith | mindbender1: I don't mean the format function in common lisp - the clojure function called cl-format |
| 00:56 | razum2um | justin_smith: perhaps in practice you're right and i need to write more cljs %) |
| 00:56 | mindbender1 | justin_smith: yeah. The docstring points there. |
| 00:56 | justin_smith | mindbender1: what you link to is different - it's not about the ascii base 2 rep, it's about outputting raw bytes |
| 00:56 | mindbender1 | okay |
| 00:56 | mindbender1 | thanks for clarifying |
| 00:57 | justin_smith | razum2um: I think it's something about which reasonable people can disagree, you asked about the rationale so I do my best to present it |
| 00:57 | razum2um | justin_smith: but actually appearence of cljx points on the fact, that there is already a huge amount of cljs code, what are companies who do have them? |
| 00:58 | justin_smith | razum2um: my previous employer, who I now do some contracting for, has some cljs code |
| 00:59 | justin_smith | razum2um: for example here http://www.onenorthpdx.com/ |
| 01:10 | mindbender1 | justin_smith: can't cl-format output hex as well? |
| 01:10 | mindbender1 | can |
| 01:10 | justin_smith | ,(pprint/cl-format nil "~x" 99999) |
| 01:10 | clojurebot | #<CompilerException java.lang.RuntimeException: No such namespace: pprint, compiling:(NO_SOURCE_PATH:0:0)> |
| 01:11 | justin_smith | ,(clojure.pprint/cl-format nil "~x" 99999) |
| 01:11 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint> |
| 01:11 | justin_smith | ,(require '[clojure.pprint :as pprint]) |
| 01:11 | clojurebot | nil |
| 01:11 | justin_smith | ,(pprint/cl-format nil "~x" 99999) |
| 01:11 | clojurebot | "1869f" |
| 01:12 | justin_smith | ,(pprint/cl-format nil "~x" 16rdeadbeef) |
| 01:12 | clojurebot | "deadbeef" |
| 01:12 | justin_smith | ,16rdeadbeef |
| 01:12 | clojurebot | 3735928559 |
| 01:13 | mindbender1 | okay. thanks |
| 01:43 | mindbender1 | ,(pprint/cl-format nil "~2,8,'0r" x) |
| 01:43 | clojurebot | #<CompilerException java.lang.RuntimeException: No such namespace: pprint, compiling:(NO_SOURCE_PATH:0:0)> |
| 01:44 | mindbender1 | ,(require '[clojure.pprint :as pprint]) |
| 01:44 | clojurebot | nil |
| 01:44 | justin_smith | x is still unbound |
| 01:44 | mindbender1 | ,(pprint/cl-format nil "~2,8,'0r" 5) |
| 01:44 | clojurebot | "00000101" |
| 01:44 | mindbender1 | just wanted to say thanks |
| 01:44 | justin_smith | np |
| 01:54 | marshall_ | hey clojure |
| 01:54 | justin_smith | hello |
| 01:55 | marshall_ | i'm almost 100% completely new to clojure and java. I'm trying to run a simple web service that uses a cool clojure library and i'm getting this error: https://gist.github.com/anonymous/3519fa9c8b5714d209fd |
| 01:55 | marshall_ | is it something simple that i just don't understand? syntax maybe? |
| 01:57 | TEttinger | marshall_: just off the top of my head, you have a vector that contains just :post, could it be expecting and converting to a hash-map (which needs an even number of entries, 1 key to 1 value) |
| 01:57 | TEttinger | :access-control-allow-methods [:post] |
| 01:57 | TEttinger | that part |
| 01:57 | TEttinger | oh! |
| 01:58 | marshall_ | TEttinger: yeah, that's the part that clojure was complaining about |
| 01:59 | marshall_ | i just pasted from here: https://github.com/r0man/ring-cors |
| 01:59 | TEttinger | it apparently converts all the args to wrap-cors to a hash-map, you should double-check the usage of that code (it seems like it's a macro) |
| 01:59 | marshall_ | i only want to allow the POST method, so I removed the other methods from that part |
| 02:01 | TEttinger | oh, gotcha |
| 02:01 | TEttinger | it has to do with -> |
| 02:01 | justin_smith | marshall_: take out app-routes |
| 02:01 | justin_smith | from the wrap-cors call |
| 02:01 | justin_smith | it throws off the hash-map construction |
| 02:02 | TEttinger | -> is called a threading macro, it takes an initial value and threads it (not concurrency threads, like threading a needle) by inserting it as the first arg to the next function given. then the result of that is inserted as the first arg to the function after that, and so on |
| 02:03 | TEttinger | ,(-> 100 (+ 10 10) (/ 12)) |
| 02:03 | clojurebot | 10 |
| 02:03 | TEttinger | so that takes 100, then makes the next piece into (+ 100 10 10) getting 120, then makes the next piece into (/ 120 12) getting 10 |
| 02:04 | fairuz | ,(->> 100 (+ 10 10) (/ 12)) |
| 02:04 | clojurebot | 1/10 |
| 02:04 | TEttinger | and ->> does the same thing with the thread inserting in the last argument position |
| 02:05 | marshall_ | ok |
| 02:06 | TEttinger | so what justin_smith is saying is, app-routes is already supplied as the first arg by -> , so when you have it again it treats it as part of the hash-map it's constructing and you and up with an odd number of elements it tries to pair into keys and values |
| 02:06 | marshall_ | ahh I see |
| 02:06 | marshall_ | that's a handy feature |
| 02:06 | TEttinger | quite! |
| 02:07 | marshall_ | i think they call that a currying function in javascript |
| 02:07 | marshall_ | or i guess in most other languages |
| 02:09 | TEttinger | kinda, -> actually works a bit differently. we have currying in the form of a function that returns functions, called partial |
| 02:09 | TEttinger | (doc partial) |
| 02:09 | clojurebot | "([f] [f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & ...]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args." |
| 02:10 | TEttinger | ,(map (partial + 10) [1 2 3]) |
| 02:10 | clojurebot | (11 12 13) |
| 02:10 | marshall_ | hmm |
| 02:10 | marshall_ | awesome |
| 02:10 | TEttinger | map I think is called map in javascript? |
| 02:11 | TEttinger | map, apply, filter are some of the most commonly used functions in clojure |
| 02:11 | marshall_ | map in javascript is when you apply a function to the elements of an array and replace each element with the result of that function |
| 02:11 | TEttinger | yep |
| 02:11 | TEttinger | here, it returns a new collection, with state possibly shared |
| 02:11 | TEttinger | that's just an optimization clojure does |
| 02:12 | marshall_ | [1,2,3].map(function(num){ return num +1 }) // >> [2,3,4] |
| 02:12 | marshall_ | i removed the app-routes parameter |
| 02:12 | marshall_ | but now I get a 404 for my one route |
| 02:13 | marshall_ | could it be the order of my middleware? |
| 02:13 | TEttinger | but you don't have to think about defining some collection, running a map on it several times in an uncertain order, and then the collection was changed in some weird order the next time you use it -- that doesn't happen in clojure |
| 02:13 | TEttinger | uh, I am not familiar with ring |
| 02:14 | marshall_ | hmm |
| 02:14 | TEttinger | it looks like wrap-cors returns something that expects one arg? |
| 02:14 | TEttinger | https://github.com/r0man/ring-cors/blob/master/src/ring/middleware/cors.clj#L67 |
| 02:17 | marshall_ | what's clojure really good for? what do you use it for? |
| 02:17 | marshall_ | i'm coming from python and node.js |
| 02:17 | marshall_ | javascript |
| 02:19 | justin_smith | marshall_: it makes concurrency sane, and once you "get it", it helps facilitate a programming style that eliminates incidental complexity |
| 02:19 | shane1 | It's jvm based, so I use it for doing functional programming with interop with java |
| 02:19 | justin_smith | marshall_: part of that is the idioms / supplied libs, but things like immutibility really help with that |
| 02:20 | justin_smith | marshall_: I wouldn't use it if I need low ram usage or fast startup, but for a process that can use as much ram as it might need, and stays running a long time, it is awesome |
| 02:23 | marshall_ | justin_smith: ahh i see |
| 02:23 | marshall_ | shane1, justin_smith: thanks |
| 02:26 | justin_smith | marshall_: for a proper function written to act on immutible data, all you need to understand in order to understand what that function does is what it explicitly acceses in the body. This is a major game changer that effects everything from code reading, to unit testing, to refactoring. |
| 02:27 | justin_smith | marshall_: also code reuse, it is easier to write modular functions that can be reused if you know they contain no implicit dependencies or state |
| 02:29 | marshall_ | interesting |
| 02:30 | marshall_ | anybody have experience with ring? I'm trying to use CORS middleware |
| 02:30 | justin_smith | yes, I use ring all the time |
| 02:33 | marshall_ | justin_smith: what am I doing wrong here? https://gist.github.com/jeffmarshall/b85a3f5fa6fe0e307112 |
| 02:33 | marshall_ | i only have one route and it gives me a 404 now that I've included the cors middleware |
| 02:34 | justin_smith | marshall_: I don't know that particular middleware, but it seems that it only allows post, and only allows requests from that specific host regex? |
| 02:35 | marshall_ | hmm |
| 02:35 | marshall_ | ok |
| 02:37 | justin_smith | marshall_: I am not sure because I don't know that middleware though |
| 02:38 | marshall_ | justin_smith: have you ever done anything in ring with CORS? |
| 02:41 | justin_smith | marshall_: no I have not |
| 02:47 | marshall_ | justin_smith: dang |
| 02:48 | justin_smith | marshall_: but the quantity of things to know about ring that you don't know is probably smaller than the quantity of things about cors that I don't know, and if we discuss it we can probably sort out what is going on |
| 02:48 | justin_smith | or is it visa versa? no matter |
| 02:56 | justin_smith | marshall_: I am working on a deploy to staging so my client can verify some work, (deploying a ring site even :)) but I can definitely help you sort this out afterward if you like |
| 04:26 | sveri80 | Hi, I am trying emacs again and started a repl in my project and connected to it with cider, now, then I try to load a buffer with cider-load-current-buffer, nothing happens in the connected repl, what is wrong there? |
| 05:41 | vyvup | hi, I am trying to use ring.server.standalone from the REPL iso. using lein ring server-headless. For some reason their auto-reload behavior is slightly different, does anyone know why? |
| 05:42 | vyvup | e.g. changing strings inside a defroutes macro do not update using standalone, but do in lein |
| 05:43 | vyvup | looking at the sources I couldn't find a real difference between how they handle things |
| 05:55 | clgv | vyvup: I haven't used these modes (I guess). but you'll only get updates when the server runs in the same repl you use to update your code |
| 05:55 | clgv | errr. function implementation instead of code. |
| 05:56 | clgv | vyvup: for routes you usually need to pass the variable (instead of the value) of the routes constant or routes function to the call that starts the server |
| 06:06 | vyvup | clgv: see ix.io/eZp for handler code |
| 06:06 | vyvup | the repl commands that i use are there inside comments |
| 06:07 | vyvup | clgv: I am sorry but don't quite understand what you mean |
| 06:08 | clgv | vyvup: change your startup to (def server (ring.server.standalone/serve #'clojure-testapp.core.handler/app)) |
| 06:08 | vyvup | ok, will try |
| 06:08 | clgv | vyvup: this way you have an indirection through the variable and get the latest changes |
| 06:09 | clgv | vyvup: you know about refheap.com ? |
| 06:09 | vyvup | nope, but now i do :) |
| 06:12 | vyvup | hmm, still does not work: what does the #' combination do? |
| 06:12 | TEttinger | ##(clojure.string/join ", " (range 500)) |
| 06:12 | lazybot | ⇒ "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, ... https://www.refheap.com/92509 |
| 06:13 | TEttinger | neat feature of lazybot is the automatic link to refheap for long printed returns |
| 06:13 | vyvup | clgv: the namespace is reloaded: the do-bye function to return another string it updates correctly |
| 06:13 | TEttinger | vyvup: it's the var-quote , it's documented at the clojure site but there's another guide out there |
| 06:14 | TEttinger | http://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/ |
| 06:14 | clgv | TEttinger: haha great |
| 06:14 | TEttinger | it's a great guide |
| 06:14 | vyvup | TEttinger: ah, nice :) |
| 06:15 | clgv | vyvup: yeah, it should reload your routes assigned to the variable "app" |
| 06:15 | vyvup | yes, but it also did that without the #' |
| 06:15 | clgv | vyvup: do you reload the namespace where "app" is defined or just reevaluate the definition of "app"? |
| 06:16 | clgv | vyvup: didn't you say your routes were not updated? |
| 06:16 | vyvup | I depend on the reload behavior of (serve) |
| 06:17 | clgv | if `serve` is not a macro you should pass the variable `app` |
| 06:17 | vyvup | well, they are reloaded partly: everything outside the macro definition is reloaded, but e.g. changing the string returned by "/hello" does not propagate |
| 06:18 | clgv | vyvup: yes, that is because you do not use the var ;) |
| 06:18 | vyvup | hmm, but when I do use the var it also does not work |
| 06:18 | clgv | vyvup: you have to pass the var and you need to reevaluate the whole namespace or: first `app-routes` and then `app` |
| 06:20 | vyvup | ah, it seems I screwed up something else :) |
| 06:23 | vyvup | clgv: yay, works \o/ thanks! I will read up on the macro stuff |
| 06:28 | TEttinger | (inc clgv) |
| 06:28 | lazybot | ⇒ 32 |
| 06:47 | clgv | thanks |
| 07:01 | luxbock | is it just me or has the syntax hilighting for Clojure code at Github got significantly worse? |
| 07:04 | jonathanj | is there a solution to the crappy let/with-open nesting you get when you need things to be defined in a certain order? |
| 07:05 | jonathanj | (let [path (temp-file)] (with-open [output (output-thing path)] (let [obj (Obj. output)] ... |
| 07:05 | jonathanj | i need to return path, so i can't just inline it |
| 07:09 | SagiCZ1 | i dont understand how could i not care about types of my sequences when conj appends to beginning or end depending on wheter its a vector or not.. thats absolute madness |
| 07:31 | raspasov | SagiCZ1: do you have specific example in mind? |
| 07:33 | borkdude | SagiCZ1 of course you care, but you usually know what you're dealing with |
| 07:33 | SagiCZ1 | when i call (last (conj coll)) for example.. |
| 07:33 | SagiCZ1 | borkdude: no i dont.. some clojure functions return random weird types how am i supposed to know what they return |
| 07:34 | borkdude | SagiCZ1 they don't return random types. most sequence functions return lazy sequences |
| 07:34 | SagiCZ1 | for example take-last returns PersistentVector, or PersistentVector$ChunkedSeq, or clojure.lang.Cons depending on the constellation of stars i guess |
| 07:34 | clgv | luxbock: it's just you. the colors and fonts change afaik |
| 07:34 | borkdude | ,(doc take-last) |
| 07:34 | clojurebot | "([n coll]); Returns a seq of the last n items in coll. Depending on the type of coll may be no better than linear time. For vectors, see also subvec." |
| 07:34 | borkdude | It returns a seq. |
| 07:35 | SagiCZ1 | ,(type (take-last 2 [5 4 3 2 0])) |
| 07:35 | clojurebot | clojure.lang.PersistentVector$ChunkedSeq |
| 07:35 | SagiCZ1 | looks like PersistentVector$ChunkedSeq to me |
| 07:35 | borkdude | (conj (take-last 2 [1 2 3]) 0) |
| 07:35 | borkdude | ,(conj (take-last 2 [1 2 3]) 0) |
| 07:35 | clojurebot | (0 2 3) |
| 07:35 | borkdude | that's perfectly predicable |
| 07:35 | borkdude | SagiCZ1 yes, PersistentVector.....Seq <- seq |
| 07:35 | clgv | SagiCZ1: that is a Seq just an implementation detail which class provides the seq methods ;) |
| 07:35 | SagiCZ1 | but why does it return java.lang.Cons sometimes? |
| 07:36 | SagiCZ1 | i mean clojure.lang.Cons |
| 07:36 | raspasov | SagiCZ1: in most cases you don't care about either of those, if you have a bigger example or gist we might be able to suggest more constructively - usually there's a nice idiomatic way to do things |
| 07:36 | borkdude | ,(type (list 0)) |
| 07:36 | clojurebot | clojure.lang.PersistentList |
| 07:36 | borkdude | ,(type (list)) |
| 07:36 | clojurebot | clojure.lang.PersistentList$EmptyList |
| 07:36 | clgv | &(-> clojure.lang.Cons ancestors) |
| 07:36 | lazybot | ⇒ #{clojure.lang.ASeq clojure.lang.Sequential clojure.lang.IObj java.util.Collection java.lang.Iterable clojure.lang.Seqable clojure.lang.Obj java.lang.Object java.util.List clojure.lang.IMeta java.io.Serializable clojure.lang.IHashEq clojure.lang.ISeq clojure.lang.IPersistentCollection} |
| 07:36 | borkdude | SagiCZ1 I don't even remember what returns a Cons, and I work with clojure pretty much every day |
| 07:36 | borkdude | SagiCZ1 not important |
| 07:37 | clgv | SagiCZ1: cons ia a seq as well as you can see above ;) |
| 07:37 | SagiCZ1 | i am acessing only last n itemes from a vector.. if i use it as is, it works fine.. if i call (take-last (* 2 n) coll) on that vector before that, my program no longer works |
| 07:37 | clgv | borkdude: not-so-lazy lazy functions do that sometimes, because there impl starts with `cons` instead of `lazy-seq` |
| 07:37 | raspasov | as a rule of thumb in Clojure, you try to stick to vectors [1 2 3] or maps {:a 1 :b 2}; and you remember that map, filter, and reduce return a sequence |
| 07:38 | borkdude | yes, and if you really want to keep it strict, use mapv, filterv or transducers |
| 07:38 | clgv | SagiCZ1: you mean two time take-last? |
| 07:38 | clgv | SagiCZ1: the problem is take-last returns a seq and does not preserve the type vector |
| 07:39 | raspasov | SagiCZ1: use subvec for vectors |
| 07:39 | SagiCZ1 | clgv: isnt that what i am talking about? |
| 07:39 | clgv | SagiCZ1: you could also implement as special take-last via sub-vec |
| 07:39 | borkdude | ,(vec (take-last 2 (range 10)) |
| 07:39 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 07:39 | raspasov | https://clojuredocs.org/clojure.core/subvec |
| 07:39 | borkdude | ,(vec (take-last 2 (range 10))) |
| 07:39 | clgv | SagiCZ1: no. because take-last always returns seq and you talk about alternating return types |
| 07:39 | clojurebot | [8 9] |
| 07:39 | raspasov | use subvec, it's guaranteed O(1) |
| 07:40 | clgv | splitting hairs: take-last is O(1) as well - just not the realization part ;) |
| 07:40 | borkdude | use sequence functions and don't care about concrete types, until you expose them. premature optimization if you do I think |
| 07:40 | SagiCZ1 | clgv: but sometimes it returns PersistentVector$chunkedSeq and sometimes clojure.lang.Cons .. andi guess my program depends on it for some reason |
| 07:40 | clgv | SagiCZ1: both are seqs just different implementations |
| 07:40 | Bronsa | SagiCZ1: those two types behave the same way unless you are explicitely testing for instanceness |
| 07:41 | clgv | no it does not. it might depend on the fact that you assume a vector where you get a sequence |
| 07:41 | SagiCZ1 | ok thanks.. there is some super weird bug then.. i guess im just going crazy |
| 07:41 | Bronsa | SagiCZ1: when clojure talks about returning a seq, it means it will return an object whose type implements ISeq |
| 07:41 | Bronsa | no concrete type is guaranteed |
| 07:41 | raspasov | SagiCZ1: again, feel free to post a larger gist, we might be able to suggest something better |
| 07:41 | SagiCZ1 | i use the return type in these functions: |
| 07:41 | SagiCZ1 | apply, count, nth, last |
| 07:41 | SagiCZ1 | shouldnt all these work fine for both types? |
| 07:43 | raspasov | it gets subtle, for example nth on a sequence is O(N) https://clojuredocs.org/clojure.core/nth |
| 07:43 | raspasov | for some details I recommend https://www.youtube.com/watch?v=iQwQXVM6oiY |
| 07:43 | Bronsa | SagiCZ1: yes, they should. can you paste a gist with the code that you're talking about as the other suggested? |
| 07:44 | SagiCZ1 | Bronsa: its spread through some files, i will look into it more and then construct some minimal example |
| 07:45 | Bronsa | SagiCZ1: early on you said that take-last returns a PersistentVector, that's never the case by the way. |
| 07:49 | SagiCZ1 | ,(type (take-last 3 [2 0]) |
| 07:49 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 07:49 | SagiCZ1 | ,(type (take-last 3 [2 0])) |
| 07:49 | clojurebot | clojure.lang.PersistentVector$ChunkedSeq |
| 07:49 | SagiCZ1 | Bronsa: ok i guess i get confused.. im trying to solve this bug for about 5 hours now.. |
| 07:56 | clgv | SagiCZ1: build small composable functions, test these individually |
| 09:14 | si14 | urgh. is there any reason why Lein can skip local .m2 repo? I have my Datomic installed there, and yet lein deps fails |
| 09:22 | hyPiRion | si14: different Datomic versions – I don't think lein would check if the version is already there |
| 09:22 | hyPiRion | si14: you don't have to use lein deps anymore though, fyi |
| 09:24 | si14 | hyPiRion: yeah, lein repl also fails :) versions are same |
| 09:25 | si14 | ah, I see: ls ~/.m2/repository/com/datomic/datomic-pro/0.9.4956 > datomic-pro-0.9.4956.jar.sha1 datomic-pro-0.9.4956.pom.sha1 _maven.repositories _remote.repositories |
| 09:25 | hyPiRion | si14: yes |
| 09:26 | si14 | hyPiRion: looks like a maven/Datomic bug then, because mvn build finishes without errors |
| 09:29 | hyPiRion | si14: Perhaps, but it may be that they store it somewhere else. Why the directory contains the sha but not the jar, I don't know. |
| 09:31 | si14 | finally solved it. it seems that if you use remote repository and then switch to local one, mvn install will not actully install datomic locally |
| 09:32 | si14 | you need to remove ~/.m2/repository/com/datomic manually first |
| 09:37 | TimMc | hyPiRion: I superstitiously run `lein do clean, deps, compile, javac, midje, junit, uberjar` when I build. |
| 09:39 | hyPiRion | TimMc: Let's :prep-task ourself? |
| 09:40 | hyPiRion | sounds reasonable. |
| 09:41 | fairuz | anyone use Titanium here? |
| 09:42 | csd_ | anyone around that hosts on heroku? |
| 09:43 | daniel__ | my laptop has some titanium in it |
| 09:43 | fairuz | daniel_ :) |
| 09:46 | clgv | ~anybody |
| 09:46 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 09:47 | csd_ | :) |
| 09:47 | csd_ | my sql server connection seems to be timing out on heroku. i'm wondering what the best way to fix it is. |
| 09:47 | csd_ | happens after like 30 or so minutes of inactivity |
| 09:48 | TimMc | I don't think Heroku supports persistent connections like that. |
| 09:48 | csd_ | do you know how to have korma reconnect to the db in that case? i was looking through the source and it wasnt clear to me how to do it |
| 09:49 | jonathanj | why is the result of (if-let [{x :x} {:not-x 5}] x "nope") different to (if-let [x (:x {not-x 5})] x "nope")? |
| 09:49 | jonathanj | err, :not-x in the second example |
| 09:49 | TimMc | csd_: Wait, Korma relies on a persistent connection? What do you mean by timing out, exactly? |
| 09:49 | jonathanj | ,(if-let [{x :x} {:not-x 5}] x "nope") |
| 09:50 | clojurebot | nil |
| 09:50 | jonathanj | ,(if-let [x (:x {:not-x 5})] x "nope") |
| 09:50 | clojurebot | "nope" |
| 09:50 | csd_ | TimMc: I think so? Because that's what I'm relying on and and it doesn't seem to be reconnecting right away. |
| 09:50 | csd_ | What happens is that I have to make two http requests. The first fails and returns a blank page, which seems to reconnect to the sql server. And then the second request works. |
| 09:51 | fairuz | I can connect OK when I run Titan DB on the same machine as my app, but when I try to connect to a remote Titan DB, it fails with IllegalArgumentException. I'm using Titanium library to connect to this DB. Any advise on this error? |
| 09:55 | csd_ | I suppose I could have my app do something like SELECT 1 every 5 minutes. I think that might work. |
| 09:58 | xeqi | jonathanj: the if portion is checking against {x :x}. This will always be truthy. Destructuring doesn't effect the if portion |
| 09:58 | jonathanj | xeqi: ah, okay |
| 09:59 | jonathanj | xeqi: thanks |
| 10:00 | xeqi | well, checking against {:not-x 5}, which is truthy |
| 10:06 | jonathanj | is putting complex if-let forms in let-like bindings usually a good idea or not? |
| 10:06 | jonathanj | (i'm guessing if i'm asking this, it's probably not) |
| 10:10 | csd_ | i wouldn't want to sacrifice clarity for brevity personally |
| 10:12 | clgv | jonathanj: depends. you'd have to show examples to judge |
| 10:13 | jonathanj | is there a preferred paste-bin for this channel? |
| 10:14 | clgv | refheap.com |
| 10:15 | clgv | or something else with clojure syntax highlighting and without tons of ads ;) |
| 10:15 | clgv | gists on github work as well |
| 10:15 | xemdetia | Was refheap ever compromised or something? |
| 10:16 | clgv | why? |
| 10:16 | clojurebot | clgv: because you can't handle the truth! |
| 10:16 | clgv | clojurebot: right |
| 10:16 | clojurebot | Gabh mo leithscéal? |
| 10:16 | jonathanj | https://gist.github.com/jonathanj/30530c685d44cf45fbb7 |
| 10:16 | xemdetia | I'm just getting a warning when I tried to look there |
| 10:16 | xemdetia | oh well, probably just an oversight |
| 10:16 | clgv | humm I dont get any |
| 10:17 | borkdude | refheap rules |
| 10:17 | clgv | xemdetia: firefox accepts the ssl certificate as valid |
| 10:17 | borkdude | because Raynes built it |
| 10:17 | clgv | xemdetia: is someone eavesdropping on you? |
| 10:18 | clgv | xemdetia: looks fine to me. could be improved with some-> |
| 10:18 | clgv | jonathanj: ^^ |
| 10:18 | xemdetia | clgv, yes- employer is and it just gets flagged as possibly malicious |
| 10:18 | xemdetia | that's why I was curious |
| 10:18 | jonathanj | clgv: some->? |
| 10:19 | clgv | jonathanj: ah wait, cond-> |
| 10:19 | borkdude | conj-> |
| 10:20 | jonathanj | how would you rewrite it? |
| 10:20 | clgv | jonathanj: page (:signature options), input-path (cond-> input-path page (vector (fill-fields page))) |
| 10:21 | clgv | jonathanj: you could also pull `page` in a local scope within a `let` surrounding the `cond->` |
| 10:22 | clgv | jonathanj: I'd recommend not to do "input-path' (some-expr input-path)" you'll probably for get ' or add it to the wrong symbol which bad since it is visually hard to detect |
| 10:23 | clgv | *forget |
| 10:23 | jonathanj | can i shadow existing names? |
| 10:23 | clgv | jonathanj: yeah |
| 10:24 | jonathanj | is the name only bound after evaluating the RHS of the let expression? |
| 10:25 | clgv | jonathanj: you could say so. the result of the RHS expression is referred to via the name in the remaining scope |
| 10:26 | jonathanj | clgv: your cond-> example, what comes before the "page (:signature" bit? |
| 10:26 | jonathanj | oh, i see, it's in the containing let |
| 10:27 | clgv | yeah exactly |
| 10:27 | clgv | but you can just use (let [page (:signature options)] (cond-> input-path page (vector (fill-fields page)))), so the name `page` is not bound in the remaining scope |
| 10:29 | jonathanj | yeah, that code i pasted is already in an existing let (as i mentioned), the let alignment is getting quite... unmanageable |
| 10:29 | jonathanj | thanks, that helped |
| 10:30 | clgv | jonathanj: maybe you could use smaller functions then |
| 10:32 | jonathanj | clgv: yes, that is almost certainly likely |
| 10:32 | jonathanj | i'm enhancing what was my first ever clojure application |
| 10:34 | jonathanj | if i have a function that takes ±7 arguments, is it preferable to start passing a map and using map destructuring instead of having a huge pile of positional arguments? |
| 10:34 | jonathanj | i guess it's more writing from the caller's perspective but it's certainly a lot more readable |
| 10:37 | clgv | jonathanj: maybe you should organize the data in a map in the first place? |
| 10:41 | jonathanj | clgv: hrm, well it's mostly wrestling command-line options to call some Java code |
| 10:41 | jonathanj | but i'll take a look at refactoring once i'm done implementing the enhancement |
| 10:41 | jonathanj | so i'm getting this warning: Reflection warning, clj_neon/core.clj:262:11 - call to setField can't be resolved. |
| 10:42 | clgv | jonathanj: is clj-neon your implementation= |
| 10:42 | jonathanj | yes |
| 10:42 | jonathanj | i'm not quite sure how to convey which overload i'm trying to call, i was under the impression there was exactly one 2-argument implementation of setField |
| 10:43 | jonathanj | https://gist.github.com/jonathanj/f5a419717c782a827b0d |
| 10:43 | clgv | ok so in your java interop, it is either not clear which type the object has or you must specify the types of the arguments to resolve to the correct overload |
| 10:43 | jonathanj | http://api.itextpdf.com/itext/com/itextpdf/text/pdf/AcroFields.html#setField%28java.lang.String,%20java.lang.String%29 |
| 10:43 | jonathanj | oh |
| 10:44 | clgv | jonathanj: maybe you have a different version? |
| 10:44 | jonathanj | i'm calling the method on the wrong object |
| 10:45 | jonathanj | okay, i'll stop spamming the channel with my trivialities, thanks for your help clgv |
| 10:45 | clgv | good luck |
| 11:14 | sdegutis | Are transducers as wonderful as the memes make it out to be? |
| 11:14 | sdegutis | zoom__: uhh |
| 11:14 | sdegutis | zoom__: why did you PM me some spam link just now? |
| 11:14 | hyPiRion | sdegutis: bot |
| 11:15 | borkdude | sdegutis always be decomplecting is the first meme of all |
| 11:16 | csd_ | what's the easiest way to extend a package that i'm using--a relatively small edit |
| 11:17 | csd_ | i dont really want to have to fork it |
| 11:18 | bbloom | csd_: depends on the edit and the package, but you could 1) forcibly redef a var (please don't) 2) send a patch to the maintainer 3) copy paste some of it's code in to your codebase 4) .... |
| 11:19 | bbloom | but really, forking isn't so bad when you've got an application to ship |
| 11:19 | csd_ | well i don |
| 11:19 | csd_ | dont |
| 11:19 | csd_ | this is more just for fun |
| 11:20 | csd_ | i want to override korma to send a sql command over its jdbc connection |
| 11:20 | wink | csd_: why does exec-raw not work? |
| 11:22 | csd_ | oh that should actually do it. i didnt see that |
| 11:22 | csd_ | thank you |
| 11:23 | wink | the docs are a bit.. yeah :) |
| 11:23 | csd_ | haha |
| 11:23 | wink | I fell into that trap as well. "such a cool library, why wont it let me exec sql?" |
| 11:23 | csd_ | "such a cool library, why does it have zero foreign key support" |
| 11:24 | wink | so you seem to use postgres? .oO( No one uses FKs with mysql ) |
| 11:24 | csd_ | i use mysql |
| 11:24 | csd_ | i guess i just do things the hard way |
| 11:26 | EvanR | i used foreign key constraints with mysql, at some point |
| 11:26 | wink | nah, I just find it atypical |
| 11:26 | EvanR | it was a real bitch |
| 11:26 | wink | most people don't |
| 11:26 | wink | maybe historical reasons as it was hard with 3.x or 4.x |
| 11:26 | csd_ | ive never used postgres. my brother keeps telling me to try it |
| 11:26 | EvanR | use postgres if its got to be sql |
| 11:27 | csd_ | i'd be interested to try something like couchdb at some point but there's definitely value in sticking to one thing and really knowing it |
| 11:27 | EvanR | really knowing postgres is really good |
| 11:28 | EvanR | and sql sucks |
| 11:28 | EvanR | so do key value stores |
| 11:33 | csd_ | wink: are you pretty familiar with korma? |
| 11:33 | wink | csd_: nope, used it in 2 small projects |
| 11:42 | jez0990 | hey #clojure, why is the ordering of transduce arguments opposite to the ordering of comp - is it is just a stylistic decision? |
| 11:43 | justin_s` | jez0990: each arg acts not on the output of the previous, but on the previous funcion |
| 11:43 | justin_s` | by wrapping it |
| 11:44 | nkoza | jez0990: there is a recent thread on the clojure mailing list about that exact issue |
| 11:44 | justin_s` | so it inverts the logical order |
| 11:44 | borkdude | jez0990 ah way you can remember: transducers correspond to ->> |
| 11:48 | jez0990 | justin_smith: nkoza borkdude: thank you :) |
| 11:56 | sdegutis | borkdude: Good to know, thanks. |
| 11:59 | EvanR | what is the function to convert a string of digits into a number |
| 11:59 | justin_smith | EvanR: one for each of the primitive numeric types |
| 11:59 | borkdude | or just edn/read-string |
| 11:59 | justin_smith | ,(Long/parseLong "1") |
| 11:59 | clojurebot | 1 |
| 12:00 | EvanR | parseLong, done |
| 12:00 | EvanR | ,(Long/parseLong "123e") |
| 12:00 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "123e"> |
| 12:00 | EvanR | ,(Long/parseLong "") |
| 12:00 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: ""> |
| 12:00 | borkdude | ,(read-string "123e") |
| 12:00 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: Invalid number: 123e> |
| 12:00 | EvanR | ,(Long/parseLong "-1") |
| 12:00 | clojurebot | -1 |
| 12:00 | borkdude | is that a thing, 12e3? |
| 12:00 | EvanR | i was testing what happens if the prefix is a valid number |
| 12:01 | justin_smith | 12e3 is scientific notation, dunno about 123e |
| 12:01 | EvanR | ,(Long/parseLong "12e3") |
| 12:01 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "12e3"> |
| 12:01 | borkdude | ,(read-string "12e3") |
| 12:01 | clojurebot | 12000.0 |
| 12:01 | borkdude | yeah ok |
| 12:01 | justin_smith | ,(Double/parseDouble "12e3") |
| 12:01 | clojurebot | 12000.0 |
| 12:01 | EvanR | i picked a bad letter for that test |
| 12:01 | justin_smith | :) |
| 12:01 | justin_smith | ,(Double/parseDouble "123e") |
| 12:01 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "123e"> |
| 12:01 | justin_smith | still fails as a suffix |
| 12:02 | clgv | ,(Double/parseDouble "123abc") |
| 12:02 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "123abc"> |
| 12:02 | clgv | ;) |
| 12:02 | EvanR | ,(Long/parseLong "123z") |
| 12:02 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: For input string: "123z"> |
| 12:04 | justin_smith | EvanR: for more complex sequences of data types in one string, there is of course edn/read, or the more flexible java.util.Scanner. And finally the various parser libs, of course. |
| 12:04 | sdegutis | bbloom: I wouldn't say forking isn't so bad. You've got to maintain your fork. At the very least, you've got to regularly merge from the repo you forked from to get their changes. That could get messy if they never merge your change. |
| 12:05 | bbloom | sdegutis: assumes you care to upgrade ever |
| 12:05 | sdegutis | bbloom: That said, I have done something similar with a really, really small lib, where the code is like 70 lines. But it was more of a wrapper around another lib. |
| 12:06 | sdegutis | bbloom: Right. Depends on things like whether the lib has inherent security needs, etc. |
| 12:09 | EvanR | ,(edn/read "true") |
| 12:09 | clojurebot | #<CompilerException java.lang.RuntimeException: No such namespace: edn, compiling:(NO_SOURCE_PATH:0:0)> |
| 12:09 | EvanR | ,(edn/read "123") |
| 12:09 | clojurebot | #<CompilerException java.lang.RuntimeException: No such namespace: edn, compiling:(NO_SOURCE_PATH:0:0)> |
| 12:10 | noonian | ,(clojure.edn/read-string "true") |
| 12:10 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.edn> |
| 12:10 | sdegutis | EvanR: you gotta require it |
| 12:10 | EvanR | required to require |
| 12:10 | noonian | ,(do (require '[clojure.edn :as edn]) (edn/read-string "true")) |
| 12:10 | clojurebot | true |
| 12:10 | justin_smith | ,(require '[clojure.edn :as edn]) |
| 12:10 | clojurebot | nil |
| 12:10 | justin_smith | heh, beat me to it |
| 12:10 | EvanR | ,(edn/read "123") |
| 12:10 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.io.PushbackReader> |
| 12:10 | EvanR | ,(edn/read-string "123") |
| 12:10 | clojurebot | 123 |
| 12:10 | sdegutis | ,(edn/read-string "(map map)") |
| 12:10 | clojurebot | (map map) |
| 12:11 | andyf | I worked on a project where I was used to require, but was required to use. refer madness |
| 12:11 | noonian | ,(edn/read-string "(map map in your hat)") |
| 12:11 | clojurebot | (map map in your hat) |
| 12:11 | EvanR | ,(edn/read-string "'(1 2 3)") |
| 12:11 | clojurebot | ' |
| 12:12 | justin_smith | EvanR: with read, it would also move the stream forward, so the next read would get the next token |
| 12:12 | justin_smith | but you need a pushbackreader for read |
| 12:13 | clgv | ,(read-string "'(1 2 3)") |
| 12:13 | clojurebot | (quote (1 2 3)) |
| 12:15 | justin_smith | ,(let [in (java.io.PushbackReader. (clojure.java.io/reader (.getBytes "1 2 :a [1 2 3] \"hello, world\"")))] (take-while identity (repeatedly #(try (edn/read in) (catch Exception _ nil))))) |
| 12:15 | clojurebot | justin_smith: I don't understand. |
| 12:16 | justin_smith | :P |
| 12:18 | justin_smith | ,(let [in (java.io.PushbackReader. (clojure.java.io/reader (.getBytes "1 2 :a [1 2 3] \"hello, world\"")))] (take-while identity (repeatedly #(and (.ready in) (edn/read in))))) |
| 12:18 | clojurebot | (1 2 :a [1 2 3] "hello, world") |
| 12:18 | justin_smith | there we go! |
| 12:19 | EvanR | push back reader |
| 12:19 | justin_smith | yeah, useful when you want to speculatively consume bytes, and later say "oops, I can't use that" and put them back, so another part of the code can consume them |
| 12:19 | EvanR | juke box hero |
| 12:20 | justin_smith | ? |
| 12:20 | EvanR | immediately what came to mind based only on the arity of syllables |
| 12:20 | clgv | just define a custom lazy-seq it'll end on nil ;) |
| 12:20 | EvanR | yeah "ungetc" |
| 12:21 | justin_smith | clgv: oh yeah, I could have done it with an fn making a lazy seq with self calls, yeah |
| 12:21 | EvanR | self calling a fn, does this bust the stuck potentially? |
| 12:21 | EvanR | stack |
| 12:22 | clgv | not in a lazy-seq ;) |
| 12:22 | justin_smith | EvanR: no, because lazy-seq transforms it into a thunk |
| 12:22 | EvanR | fun times |
| 12:23 | noonian | recursion is the funnest |
| 12:24 | justin_smith | noonian: also, the funnest is recursion |
| 12:25 | cbryan | justin_smith: but don't forget that recursion is the funnest |
| 12:25 | justin_smith | I propose we rename iterate to turtles |
| 12:25 | noonian | GNU has the best recursive acronyms |
| 12:26 | clgv | justin_smith: no then it would be mutual recursion ;) |
| 12:27 | justin_smith | clgv: that's recursion |
| 12:27 | clgv | justin_smith: recursion is almost recursion ;) |
| 12:28 | clgv | justin_smith: "to understand recursion you have to know someone who understands recursion" ;) |
| 12:29 | silasdavis | is there a way to get leiningen to add some arbitrary files to your jar? |
| 12:29 | clgv | silasdavis: put them under the resource path |
| 12:29 | justin_smith | clgv: I hear Heinz Von Foerster was fond of having you provide a random word, and see how long it took, starting from that word, to demonstrate a closed system of references in the dictionary. He called this the dictionary game. |
| 12:29 | EvanR | to understand recursion you need a base case to avoid an infinite regression |
| 12:29 | technomancy | silasdavis: easiest way is to plop them in resources/ put you can use :filespecs too |
| 12:30 | clgv | justin_smith: haha :D |
| 12:30 | clgv | EvanR: no, base cases take away all the fun! :P |
| 12:30 | justin_smith | clgv: his claim was that all human knowledge was recursive |
| 12:31 | noonian | infinite recursion works, its just usually not what you want unless you are making an interpreter or something |
| 12:31 | silasdavis | technomancy: thanks I thought of using resources. I didn't know about filespecs, these are vendored dependency executable binaries |
| 12:31 | justin_smith | clgv: though he preferred the term "circular" |
| 12:31 | clgv | justin_smith: there is some wikipedia game as well, to count the number of times to following the first link in an article until you end up at "Philosophy" starting at a random article |
| 12:32 | technomancy | silasdavis: resources/ is fine for that; there's no requirement that they be text |
| 12:32 | justin_smith | clgv: yeah, I have played that one too :) |
| 12:32 | SagiCZ1 | ,(-> clojure.lang.PersistentQueue/EMPTY (conj 5) (conj 42)) |
| 12:32 | clojurebot | #<PersistentQueue clojure.lang.PersistentQueue@486> |
| 12:32 | SagiCZ1 | ,(seq -> clojure.lang.PersistentQueue/EMPTY (conj 5) (conj 42))) |
| 12:32 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->, compiling:(NO_SOURCE_PATH:0:0)> |
| 12:32 | justin_smith | ,(seq (conj clojure.lang.PersistentQueue 5 42)) |
| 12:32 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IPersistentCollection> |
| 12:33 | SagiCZ1 | ,(seq (-> clojure.lang.PersistentQueue/EMPTY (conj 5) (conj 42))) |
| 12:33 | clojurebot | (5 42) |
| 12:33 | SagiCZ1 | isnt it backwards? |
| 12:33 | justin_smith | ,(seq (conj clojure.lang.PersistentQueue/EMPTY 5 42)) |
| 12:33 | clojurebot | (5 42) |
| 12:33 | clgv | justin_smith: damn! tapped in "Greek" -> "Modern Greek" -> "Greek" |
| 12:33 | justin_smith | SagiCZ1: that's what a queue does, it adds to the end, removes from the front |
| 12:33 | SagiCZ1 | justin_smith: ok i though it was the other way around, np |
| 12:34 | justin_smith | ,(seq (pop (conj clojure.lang.PersistentQueue/EMPTY 5 42))) |
| 12:34 | clojurebot | (42) |
| 12:34 | justin_smith | see, the 5 is gone |
| 12:34 | justin_smith | FIFO |
| 12:34 | SagiCZ1 | yeah.. FIFO |
| 12:34 | SagiCZ1 | 5 came first so it gets removed first |
| 12:35 | SagiCZ1 | queues usually have static size, but i guess its dynamic in clojure, right? |
| 12:35 | justin_smith | yeah |
| 12:35 | justin_smith | sometimes that is not what you want |
| 12:35 | justin_smith | java of course has bounded ones |
| 12:36 | SagiCZ1 | and if i wanted to remove more than one element by popping, can i just call pop repeatedly? |
| 12:37 | clgv | O_o |
| 12:37 | justin_smith | SagiCZ1: remember that this is a persistent data structure |
| 12:38 | SagiCZ1 | i understand it will not mutate |
| 12:38 | justin_smith | SagiCZ1: in practice you want to bind the value being removed with pop before doing that, but yeah, you can do multiple pops if you want to take multiple values off |
| 12:38 | justin_smith | SagiCZ1: maybe there is a more convenient method for this... |
| 12:39 | SagiCZ1 | i am still trying to come up with the best data structure for my problem.. cant be that hard |
| 12:39 | SagiCZ1 | vectors kinda work |
| 12:40 | hyPiRion | SagiCZ1: you can use core.async as well, if that fits |
| 12:40 | justin_smith | SagiCZ1: if I recall correctly you were taking items off on end, and adding to the other, and because you were using seq operations to do this you were losing the vector format |
| 12:41 | SagiCZ1 | justin_smith: yes |
| 12:41 | justin_smith | SagiCZ1: a queue is actually designed for this FIFO behavior that is inherent to your algorithm |
| 12:41 | justin_smith | also, as hyPiRion mentions, core.async is, among other things, an interesting DSL over queues |
| 12:42 | SagiCZ1 | i was removing the elements from the other end because i no longer needed them and because the vector was growing too much.. this would solve either constant size queue, or just using the regular peristent queue, and popping every time i conj new element once it reaches some predetermined size |
| 12:43 | SagiCZ1 | does that make any sense? |
| 12:43 | justin_smith | I think so, yeah |
| 12:43 | clgv | SagiCZ1: you can just do that, by writing a custom `queue-conj` |
| 12:44 | SagiCZ1 | clgv: true.. while experimenting i often forget that when i put some code in functions it makes it more readable but also easier to reason about. |
| 12:44 | justin_smith | SagiCZ1: why not remove items from the queue if they have been processed? |
| 12:45 | SagiCZ1 | justin_smith: because i always need last n items, not just the very last item |
| 12:45 | SagiCZ1 | n is constant |
| 12:45 | clgv | SagiCZ1: sliding window? moving averages? |
| 12:45 | justin_smith | SagiCZ1: OK, then hold onto exactly n items :) |
| 12:45 | SagiCZ1 | clgv: exactly |
| 12:47 | SagiCZ1 | so core.async has things that are handy even though i am not dealing with concurrency? |
| 12:48 | justin_smith | SagiCZ1: it can be useful for code that can be expressed in terms of reading from and writing to queues |
| 12:49 | clgv | SagiCZ1: is that code performance critical? |
| 12:50 | justin_smith | the basic concept is that all the code is connected by (chan) instances, and all the logic happens by filling and processing queues |
| 12:51 | SagiCZ1 | clgv: yes, but i dont think i should optimize it at this point too much |
| 12:53 | SagiCZ1 | justin_smith: very interesting |
| 12:53 | clgv | SagiCZ1: no not really. |
| 12:56 | SagiCZ1 | clgv: you asked if the code is performance critical, would you have any performance suggestions? |
| 12:57 | cbryan | i am not used to paredit yet. just sat there for about 5 minutes trying to delete a bracket |
| 12:58 | sdegutis | cbryan: The point of paredit is that you don't have to delete a bracket. |
| 12:58 | justin_smith | cbryan: haha - C-space / C-w still works :) |
| 12:58 | sdegutis | cbryan: You can delete an s-expression though. Or it's contents. And it'll still be balanced. |
| 12:58 | cbryan | exactly ;) |
| 12:58 | sdegutis | I've been trying to learn paredit.vim lately. |
| 12:58 | justin_smith | sdegutis: you can get in a messy spot if you copy / paste from a non paredit source though |
| 12:58 | cbryan | yep ^ that's what happened |
| 12:59 | justin_smith | cbryan: so yeah, C-space / C-w |
| 12:59 | sdegutis | justin_smith: Good point. In those cases, I edit parens within a comment, and uncomment then when it's ready. |
| 12:59 | justin_smith | or just temporarily turn off paredit |
| 12:59 | cbryan | justin_smith: thanks :p |
| 12:59 | justin_smith | sdegutis: interesting approach |
| 12:59 | sdegutis | I find it to be the easiest/quickest way. |
| 12:59 | sdegutis | And most flexible. |
| 12:59 | cbryan | sdegutis: interesting |
| 12:59 | justin_smith | sdegutis: cbryan you can also use C-q to insert the matching paren |
| 12:59 | justin_smith | so that it's balanced, and thus deletable |
| 12:59 | sdegutis | I haven't found a time when it hasn't worked. |
| 13:13 | cbryan | i named my webcrawler project "Parker" and my robots.txt project (to keep Parker in line) "Jameson". it's the little things |
| 13:13 | sdegutis | ha! |
| 13:13 | sdegutis | (inc cbryan) |
| 13:13 | lazybot | ⇒ 1 |
| 13:14 | cbryan | if i'm being honest i was fishing for an inc ;) |
| 13:14 | sdegutis | (inc cbryan) |
| 13:14 | lazybot | ⇒ 2 |
| 13:15 | clgv | seems not that difficult with sdegutis ;) |
| 13:15 | sdegutis | (inc clgv) |
| 13:15 | lazybot | ⇒ 33 |
| 13:15 | cbryan | now you're just devaluing it! ;) |
| 13:15 | sdegutis | (dec cbryan) |
| 13:15 | lazybot | ⇒ 1 |
| 13:15 | EvanR | (dec EvanR) |
| 13:15 | lazybot | You can't adjust your own karma. |
| 13:15 | sdegutis | (inc EvanR) |
| 13:15 | lazybot | ⇒ 1 |
| 13:16 | cbryan | no halloween-themed clojure(docs).org? damn |
| 13:17 | EvanR | reminds me of the old pay-per-month MUDs where you got a fixed number of role playing points to give people who role played |
| 13:17 | sdegutis | (dec cbryan) |
| 13:17 | lazybot | Do I smell abuse? Wait a while before modifying that person's karma again. |
| 13:17 | cbryan | sdegutis is out of control! |
| 13:17 | sdegutis | No lazybot I'm just being an active participant in the community. |
| 13:17 | cbryan | sdegutis: stop playing with my emotions |
| 13:17 | sdegutis | +1 |
| 13:17 | EvanR | (inc lazybot) |
| 13:17 | lazybot | ⇒ 32 |
| 13:18 | sdegutis | $karma sdegutis |
| 13:18 | lazybot | sdegutis has karma 6. |
| 13:18 | sdegutis | Oh nice. |
| 13:19 | cbryan | starting my new internship monday.. they're a java shop, maybe i can inject some clojure? :D |
| 13:20 | clgv | better not in the first week ;) |
| 13:20 | zachncst22 | Never hurts to show initiative. |
| 13:20 | clgv | I doubt the empirical truth of that statement |
| 13:20 | cbryan | haha |
| 13:20 | sdegutis | zachncst22: In this case it may :P |
| 13:21 | sdegutis | cbryan: Why not Scala instead? |
| 13:21 | sdegutis | I hear it's much faster than Clojure, if you're going for speed. |
| 13:21 | sdegutis | What's the fastest JVM language? |
| 13:21 | hfaafb | Java |
| 13:21 | clgv | sdegutis: just hack everything together in C and just call per JNI :P |
| 13:21 | sdegutis | clgv: I'd rather write in Lua tbh. |
| 13:22 | hfaafb | Just write it in Go |
| 13:22 | zachncst22 | Ugh, JNI |
| 13:22 | clgv | sdegutis: I'll let you know when the next serious post is to be expected from me ;) |
| 13:22 | SagiCZ1 | i would use Pascal |
| 13:23 | zachncst22 | Go Fortran, it's tons of fun. |
| 13:23 | EvanR | Groovy |
| 13:23 | zachncst22 | Clojure is love, Clojure is life. |
| 13:24 | clgv | guess I never use pascal again |
| 13:25 | SagiCZ1 | zachncst22: the only thing i hate about clojure is how little i know about it |
| 13:25 | clgv | SagiCZ1: change it ;) |
| 13:26 | cbryan | 4clojure taught me the most/fastest |
| 13:26 | mdrogalis | Same |
| 13:26 | zachncst22 | SagiCZ1: I agree completely. Which is why it's kicked out Scala as my 'play' language |
| 13:26 | SagiCZ1 | clgv: i usually learn by coding.. |
| 13:26 | clgv | cbryan: but it leaves knowledge holes you should fill with one of the books^^ |
| 13:26 | bbloom | (inc 4clojure) ; looking at other people's answers helped me lots |
| 13:26 | lazybot | ⇒ 3 |
| 13:28 | clgv | you can't learn the big picture with 4clojure alone... |
| 13:28 | mdrogalis | Just saying, it's a nice start. |
| 13:29 | mdrogalis | A Datomic equivalent would be fun... :D |
| 13:29 | clgv | yeah, for fast practical experience it is awesome. |
| 13:29 | the_danko | fellows, i am working through the lispcast web development video and part of it involves a postgresql database. when i try to connect, i get Exception in thread "main" org.postgresql.util.PSQLException: The server requested password-based authentication, but no password was provided., compiling:(/private/var/folders/df/0z098cs56496gxlycxf2688c0000gn/T/form-init3442633375570322721.clj:1:124) |
| 13:29 | SagiCZ1 | i read through Clojure Programming, while i consider it a great book I didn't learn all that much, i need to practice it a lot |
| 13:30 | justin_smith | the_danko: did you specify any password in your database config? |
| 13:30 | the_danko | anyone familiar with this? i dont know sh*t about psql, and i do need to enter a password when i type in "psql webdev" |
| 13:30 | sdegutis | hfaafb: phshaw |
| 13:30 | the_danko | justin_smith: no, seems like we are onto something! |
| 13:30 | the_danko | justin_smith: (def db "jdbc:postgresql://localhost/webdev") |
| 13:31 | justin_smith | {:classname com.postgresql.jdbc.Driver :subprotocol "postgresql" :host "localhost" :database "webdev" :user "youruser" :password "yourpassword"} |
| 13:31 | cbryan | the_danko: how are you actually connecting? |
| 13:31 | cbryan | or that :p |
| 13:32 | the_danko | cbryan: execute in clojure jdbc |
| 13:32 | the_danko | justin_smith: thanks! trying now! |
| 13:32 | justin_smith | the_danko: or, alternatively, construct the URL with all that info as a string, but easier to use the map form as above |
| 13:33 | EvanR | lispcast = eric normand? |
| 13:33 | the_danko | evanr: correcto |
| 13:33 | EvanR | ok |
| 13:34 | the_danko | justin_smith: Caused by: java.lang.ClassNotFoundException: com.postgresql.jdbc.Driver |
| 13:34 | justin_smith | the_danko: correction :classname "org.postgresql.Driver" |
| 13:34 | justin_smith | the rest should work |
| 13:35 | justin_smith | I was lazy, and I was looking at my mysql config on my most recent project :P did a poor on-the-fly translation :) |
| 13:37 | the_danko | justin_smith: hmm, missing a required parameter |
| 13:37 | justin_smith | does it say which one? |
| 13:38 | justin_smith | :classname :subprotocol :host :database :user :password |
| 13:38 | justin_smith | I specified all of those right? |
| 13:38 | the_danko | Caused by: java.lang.IllegalArgumentException: db-spec {:password "pass", :classname org.postgresql.Driver, :subprotocol "postgresql", :host "localhost", :database "webdev", :user "austin"} is missing a required parameter |
| 13:38 | the_danko | justin_smith: correct |
| 13:39 | epichero | is there a book on debugging clojure yet? |
| 13:39 | justin_smith | I think classname should be a string |
| 13:39 | justin_smith | (it is in my code for postgres at least) |
| 13:39 | epichero | i always parse name as meaning a string(in my head) |
| 13:43 | the_danko | hmm, maybesubname? i'll get googling |
| 13:43 | the_danko | maybe :subname i mean |
| 13:44 | the_danko | keep googling |
| 13:44 | the_danko | thanks again justin_smith |
| 13:46 | justin_smith | the_danko: here is an obfuscated version of a config that actually works: {:classname "org.postgresql.Driver" :subprotocol "postgresql" :host "127.0.0.1" :database "favoritedogs" :user "user1" :password "xxxx"} |
| 13:47 | the_danko | cfleming: automatic line breaks would really be awesome! |
| 13:47 | the_danko | justin_smith: thanks, trying it out now! |
| 13:50 | the_danko | justin_smith: (def db |
| 13:50 | the_danko | {:classname "org.postgresql.Driver" |
| 13:50 | the_danko | :subprotocol "postgresql" |
| 13:50 | the_danko | :user "user" |
| 13:50 | the_danko | :password "pass" |
| 13:50 | the_danko | :subname "//localhost:5432/webdev" |
| 13:50 | the_danko | :unsafe true}) worked! |
| 13:50 | the_danko | justin_smith: thanks a lot! |
| 13:50 | justin_smith | np |
| 13:50 | justin_smith | the_danko: ahh, I htink in this project I had a middle layer constructing the subname out of the host and database, sorry for that bit of noise |
| 13:51 | justin_smith | I forgot that was in there |
| 13:51 | the_danko | justin_smith: ha, you led me in the right direction. i wasn't aware of the map form. |
| 13:52 | justin_smith | the_danko: for extra credit you can throw a :datasource in there with a connection pooling class :) |
| 13:52 | cbryan | yay! now i can scroll irssi with my mouse. the future is now |
| 13:52 | EvanR | the_danko: jealous of the formatting of that map |
| 13:52 | the_danko | EvanR: ha, i stole it from here https://github.com/budu/lobos/blob/master/test/lobos/test.clj |
| 13:52 | justin_smith | I am sure there is a dodgy emacs library that does it automatically |
| 13:53 | the_danko | justin_smith: with hope, cfleming will be rocking this shit soon in cursive! |
| 13:54 | the_danko | the more times you say something, the truer it becomes |
| 13:54 | Bronsa | align-cljlet can indent map literals that way |
| 13:54 | Bronsa | https://github.com/gstamp/align-cljlet |
| 13:54 | justin_smith | Bronsa: I knew it! and there is a small chance it isn't even dodgy |
| 13:54 | Bronsa | justin_smith: it works really well |
| 13:55 | the_danko | cfleming: good code formatting will be huge for making this thing really catch on. it's hard for the intellij/eclipse java guys to live without. ok, that's the last tiem for today! |
| 13:56 | mmeix | Light Table has very good indenting, like it |
| 13:58 | epichero | I have spent so much time trying out different solutions on vim and emacs for clojure workflow |
| 14:19 | mdrogalis | I'm trying to do some stream analysis with Clojure. Can anyone think of something interesting to do with a tweet stream? Creativity is running dry. |
| 14:20 | tbaldridge | mdrogalis: pick a hot topic, then a set of words that express emotion, somehow figure out what the public's average view of a given topic is. |
| 14:21 | tbaldridge | mdrogalis: heard about some group that does that for motivational speakers. They generate live feeds of what the public thinks of the speaker via the tweets of the people watching the talk. |
| 14:21 | amalloy | tbaldridge: (constantly "shallow and trite") |
| 14:21 | tbaldridge | (inc amalloy) |
| 14:21 | lazybot | ⇒ 184 |
| 14:22 | cbryan | tbaldridge: tweetwall |
| 14:22 | amalloy | justin_smith: i'm not a fan of auto-aligned let/cond/map/whatever. it makes it hard for the next guy to edit your code without making it look stupid |
| 14:22 | mdrogalis | tbaldridge: Hah, very cool. |
| 14:23 | mdrogalis | I think I'll do that! Thanks! |
| 14:23 | justin_smith | mdrogalis: another possibility: try to predict who will end up following / favoriting / retweeting |
| 14:23 | cbryan | mdrogalis: http://tweetwall.com/ inspiration :p |
| 14:24 | cbryan | would it be better style to have each defrecord of a protocol in its own namespace, or in the same namespace as the protocol? or does it really depend.. |
| 14:24 | justin_smith | amalloy: clearly the solution is for everyone to use identical, policy approved, emacs config |
| 14:24 | justin_smith | (nor am I a fan of that kind of indenting btw) |
| 14:24 | amalloy | for reasons that i don't recall, i forked align-let myself instead of using that clojure one, for the brief period that ninjudd insisted i align things: https://github.com/amalloy/align-let/commit/a6ece33751735d83b9de08377fd3919f84fe8641 |
| 14:24 | mdrogalis | justin_smith cbryan: Thanks. :D |
| 14:25 | dbasch | mdrogalis: I did a word cloud generator a while back, just ran it for the word “giants” http://images.diegobasch.com/giants.png |
| 14:25 | EvanR | is this the right place to ask about datomic advice |
| 14:25 | pandeiro | what is the rationale behind namespacing keywords and is it A Bad Idea to introduce namespaced keywords in an API that use a shortened ns portion (eg :foo/thing vs. :foo.core/thing) ? |
| 14:25 | justin_smith | mdrogalis: you could also look at what facebook / okcupid have done with their social data (facebook being able to guess who would end up in a relationship, okcupid predicting who would respond to messages, etc.) |
| 14:25 | dbasch | mdrogalis: https://github.com/dbasch/twittercloud |
| 14:25 | amalloy | EvanR: i'm pretty sure #datomic is a thing |
| 14:26 | arrdem | mdrogalis: #gamergate what could go wrong |
| 14:26 | mdrogalis | I still dont understand what gamergate is. I tried multiple times :( |
| 14:26 | mdrogalis | But, not relevant for #clojure I guess. |
| 14:26 | mdrogalis | Thanks guys ^ Ill check those links. |
| 14:27 | mmeix | Is there a guide line concerning the order of a function's arguments? |
| 14:27 | mmeix | for example: |
| 14:27 | mmeix | (defn myfn [x coll] (remove #{x} coll)) |
| 14:27 | mmeix | or |
| 14:27 | mmeix | (defn myfn [coll x] (remove #{x} coll)) |
| 14:27 | arrdem | mmeix: cols come last typically |
| 14:27 | cbryan | makes it easier to partial-ize! |
| 14:27 | amalloy | arrdem, mmeix: sequences go last; other kinds of collections usually go first |
| 14:27 | dbasch | there are examples of both |
| 14:28 | dbasch | strings usually go first |
| 14:28 | amalloy | arrdem: see, for example, update-in, assoc, etc |
| 14:29 | mmeix | ok, is there some rationale behind this, besides partializing, or is this just a stylistic thing? |
| 14:29 | the_danko | amalloy justin_smith not sure whether just was joking or not but forcing a code formatter on all developers in the company works great! |
| 14:30 | arrdem | style and allowing ->> as an idiom on sequence last functions |
| 14:30 | mmeix | ah, I see |
| 14:30 | amalloy | mmeix: ->> for sequences, -> and the unified update model for other stuff |
| 14:30 | amalloy | eg, it lets you write (swap! x update-in [:people] conj mmeix) |
| 14:30 | arrdem | the_danko: pre-commits that lint, test and reindent are awesome :D |
| 14:31 | mmeix | (notes term "unified update model") |
| 14:31 | amalloy | which wouldn't work unless update-in and conj both took their collection argument first |
| 14:32 | justin_smith | the_danko: forcing everyone to use emacs usually not so great |
| 14:32 | amalloy | mmeix: i'm probably the only person who still says it. it was a name that stuart halloway (i think) popularized years ago to describe how updating functions work together in the way i just showed |
| 14:32 | mmeix | aha! thanks |
| 14:32 | the_danko | arrdem: interesting! would love to hear more. justin_smith: ha, agreed. i made the guys to do it with eclipse and intellij (can use the same format files). |
| 14:32 | the_danko | arrdem: we did not do pre-commit checks though. also i have never heard of lint until now. |
| 14:33 | the_danko | arrdem: care to elaborate? |
| 14:33 | arrdem | the_danko: the idea is just that if you have code climate requirements (whitespace/formatting/tests/test coverage) you write git hooks that prevent code from reaching staging without satisfying all these requirements. I personally choose to inflict them on myself almost all the time. |
| 14:34 | tuft | hello clojureplex |
| 14:34 | the_danko | yo tuft! |
| 14:34 | the_danko | arrdem so you just reject commits instead of autoreformatting? |
| 14:34 | arrdem | the_danko: sure |
| 14:35 | Bronsa | the_danko: it's more useful to reject commits if the linter returns warnings or if the test fail though |
| 14:35 | mmeix | amalloy BTW: reading flatland.org/useful/ source is a great learning experience for me :-) |
| 14:35 | the_danko | Bronsa: who is this linter fellow everyone ist alking about? |
| 14:35 | arrdem | $google c lint |
| 14:35 | lazybot | [Lint (software) - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Lint_(software) |
| 14:36 | Bronsa | the_danko: http://en.wikipedia.org/wiki/Lint_(software) |
| 14:36 | arrdem | $google clojure eastwood |
| 14:36 | lazybot | [jonase/eastwood · GitHub] https://github.com/jonase/eastwood |
| 14:36 | the_danko | arrdem Bronsa ha i got that far but thanks! |
| 14:36 | the_danko | arrdem ill check out |
| 14:36 | the_danko | arrdem check it otu |
| 14:36 | arrdem | $google clojure cloverage |
| 14:36 | lazybot | [lshift/cloverage · GitHub] https://github.com/lshift/cloverage |
| 14:37 | arrdem | the_danko: ^ test coverage tool for Clojure |
| 14:38 | the_danko | arrdem and what did you mean by reindent? reformat? |
| 14:38 | amalloy | mmeix: great |
| 14:39 | arrdem | the_danko: other languages have tools like gofmt. Clojure doesn't have a good equivalent, although Emacs's clojure-mode indent is good and bbloom's fipp has a "code" mode now. |
| 14:39 | arrdem | the_danko: astyle for Java/C++/C |
| 14:40 | arrdem | bbloom: did you take the code format patches? |
| 14:40 | arrdem | looks like he did |
| 14:43 | sdegutis | Gonna tackle Transducers today! |
| 14:43 | joobus | sdegutis: don't forget to wear protection |
| 14:46 | dwmm | has anybody written a comparison of buddy and friend? |
| 14:46 | dwmm | I'm looking to use one of them with liberator and biddi |
| 14:47 | amalloy | having never heard of buddy, i'm gonna go out on a limb and say it's an attempt to rewrite friend to be less hairy, but which ultimately falls short by missing several key features |
| 14:48 | amalloy | so, take that for what it's worth |
| 14:50 | bbloom | arrdem: yeah, i merged it and tweaked it a bit |
| 14:51 | bbloom | arrdem: however, i should be clear that gofmt style code convention enforcement is a non-goal |
| 14:51 | bbloom | i'm almost exclusively interested in debugging macros |
| 14:51 | bbloom | although i guess it also helps as a starting point for hand tuned re-formatting |
| 14:53 | dwmm | thanks I'll look into it, but I'm hesitant to try it |
| 14:55 | the_danko | cfeming: how about the rainbow parantheses also? to be clear, i have a lot less experience with and confidence in this request as opposed to the formatting as a 1.5 week lisp programmer vs. a 4 year java guy, but it does look helpful. |
| 14:55 | the_danko | cfleming: how about the rainbow parantheses also? to be clear, i have a lot less experience with and confidence in this request as opposed to the formatting as a 1.5 week lisp programmer vs. a 4 year java guy, but it does look helpful. |
| 14:56 | andyf | Bronsa: Ciao. I?m refining Eastwood? wrong-tag linter, and got a t.a.j wrong-tag question for you. In a project (meltdown) there is one namespace with (defn ^Reactor create ...), no warning. This is ok, because CLJ-1232 only rears its ugly head if ^Reactor were tagged on the arg vector. |
| 14:57 | andyf | Then in another namespace, there is a call (mr/create) to that function, and there t.a.j gives a wrong-tag callback. Clojure itself gives no error here like for CLJ-1232 case. |
| 14:57 | the_danko | cfleming: the highlight matching when the cursor is near a paranthesis is great, but the always on rainbow thing could be cool. |
| 14:57 | andyf | Does t.a.j warn here because the tag is useless/ignored by Clojure? |
| 15:03 | sdegutis | Tranducers are still in a beta version of Clojure and therefore not safe to use in production yet right? |
| 15:04 | justin_smith | sdegutis: probably safer than a stable version of mongodb |
| 15:04 | sdegutis | !!! |
| 15:04 | TimMc | oh snap |
| 15:05 | andyf | sdegutis: It?s really up to your judgement. I know Sean Corfield said they are using alpha versions of Clojure 1.7.0 in production, but I don?t know if they are actually using transducers. |
| 15:05 | mdrogalis | World Singles seems to run edge everything. |
| 15:06 | justin_smith | in all seriousness, I would trust a not-yet-official version of a known reliable project over an official version of a known unreliable one. But yeah, they are not in any stable version of clojure yet. |
| 15:06 | TimMc | "MongoDB: A ship in the harbour is safe, but that's not what ships are for" |
| 15:07 | TimMc | "(ships are for moving fast and breaking things)" |
| 15:07 | justin_smith | TimMc: therefor we invite you to climb on our raft made of twine and truck tires |
| 15:08 | hiredman | but ships are but boards, sailors but men. |
| 15:14 | the_danko | so why do i need parantheses around the anonymous function here? |
| 15:14 | the_danko | (def app (-> routes wrap-params wrap-db (#(wrap-resource % "static")) wrap-server )) |
| 15:15 | justin_smith | ,(macroexpand '(def app (-> routes wrap-params wrap-db (#(wrap-resource % |
| 15:15 | justin_smith | "static")) wrap-server ))) |
| 15:15 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 15:15 | justin_smith | err |
| 15:15 | justin_smith | ,(macroexpand '(def app (-> routes wrap-params wrap-db (#(wrap-resource % "static")) wrap-server ))) |
| 15:15 | clojurebot | (def app (-> routes wrap-params wrap-db ((fn* [p1__48#] (wrap-resource p1__48# "static"))) ...)) |
| 15:15 | hiredman | ,(macroexpand '(-> a (fn []))) |
| 15:15 | clojurebot | (fn* a ([])) |
| 15:15 | hiredman | ,(macroexpand '(-> a ((fn [])))) |
| 15:15 | clojurebot | ((fn []) a) |
| 15:15 | arrdem | the_danko: you don't (def app (-> routes wrap-params wrap-db (wrap-resource "static") wrap-server)) |
| 15:15 | TimMc | the_danko: Because it's actually (fn [...] ...), and what happens to parenthesized forms when you put them in -> ? |
| 15:16 | the_danko | (macroexpand '(-> a f1 (f2)) |
| 15:16 | justin_smith | the_danko: you need a , before that |
| 15:17 | hiredman | ,'#(+ 1 %) |
| 15:17 | clojurebot | (fn* [p1__249#] (+ 1 p1__249#)) |
| 15:17 | the_danko | ,(macroexpand '(-> a f1 (f2)) |
| 15:17 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 15:17 | TimMc | ,(-> a #((((((a))))))) |
| 15:17 | clojurebot | #<sandbox$eval322$a__323 sandbox$eval322$a__323@1bd831f> |
| 15:19 | the_danko | TimMc: so it looks like (macroexpand `(-> a f1 f2)) |
| 15:19 | the_danko | is equivalent to (macroexpand `(-> a f1 (f2))) |
| 15:19 | the_danko | => (-dev-main/f2 (-dev-main/f1 -dev-main/a)) |
| 15:19 | the_danko | (macroexpand `(-> a f1 (f2))) |
| 15:19 | the_danko | => (-dev-main/f2 (-dev-main/f1 -dev-main/a)) |
| 15:19 | the_danko | (macroexpand `(-> a f1 ((f2)))) |
| 15:19 | the_danko | => ((-dev-main/f2) (-dev-main/f1 -dev-main/a)) |
| 15:20 | the_danko | TimMc: hmm, i don't know why (f2) is equivalent to f2 but not ((f2)) |
| 15:20 | justin_smith | the_danko: that's just a weird thing about -> |
| 15:21 | the_danko | justin_smith: ha, ok, well now i know! thanks. |
| 15:21 | justin_smith | the_danko: a pattern you will see is (#(f % b)) in ->> or (#(f b %)) inside ->, beause this switches arg position |
| 15:21 | TimMc | the_danko: For convenience, -> allows you to say foo instead of (foo). |
| 15:22 | justin_smith | but it is better to use as->, or an embedded cal to -> / ->> |
| 15:23 | TimMc | ,(macroexpand '(-> a b c)) |
| 15:23 | clojurebot | (c (b a)) |
| 15:23 | TimMc | ,(macroexpand '(-> a (b) (c))) |
| 15:23 | clojurebot | (c (b a)) |
| 15:23 | the_danko | justin_smith TimMc thanks ! |
| 15:23 | TimMc | ,(macroexpand '(-> a (b 1 2) (c 3 4))) |
| 15:23 | clojurebot | (c (b a 1 2) 3 4) |
| 15:23 | TimMc | the_danko: ^ This illustrates it. |
| 15:24 | TimMc | Then see hiredman's message above for why #() interacts weirdly with this. |
| 15:24 | TimMc | Finally, see if you can understand why my example above works the way it does: (-> a #((((((a))))))) |
| 15:24 | TimMc | It's a pathological example, but illustrative. |
| 15:25 | the_danko | TimMc: ok for the a b c thing, it looks like i should do this (def app (-> routes wrap-params wrap-db (wrap-resource "static") wrap-server )) |
| 15:25 | the_danko | TimMc: instead. which works. |
| 15:26 | sdegutis | How does this work? &(let [dict {'dup (fn [[x & s] _] (conj s x x)) '* (fn [[x y & s] _] (conj s (* x y)))}] (reduce #((dict %2 conj) %1 %2) () '(5 dup *))) |
| 15:26 | csd_ | Magit is pretty neat |
| 15:26 | sdegutis | (inc csd_) |
| 15:26 | lazybot | ⇒ 1 |
| 15:27 | the_danko | TimMc: cool, so i think i have the abc part. now onto hiredman. |
| 15:28 | the_danko | TimMc I love the lessons plan by the way! |
| 15:28 | justin_smith | sdegutis: looks like a forth interpreter |
| 15:28 | sdegutis | bbloom: You wrote a forth interpreter in <=140 chars!? |
| 15:28 | justin_smith | sdegutis: actually yeah, it's a small subset of forth, but it uses forth semantics with a list as a stack |
| 15:29 | justin_smith | sdegutis: where reduce is used to run the program (the words of the program being in the input) |
| 15:29 | sdegutis | That is so fricken cool. |
| 15:29 | sdegutis | I wonder how else you could do it, without reduce? There's another core function that I think could do it that's just on the tip of my tongue. |
| 15:30 | justin_smith | sdegutis: the idea with forth is words take N words off the stack, do some operation, then put N words back on |
| 15:30 | bbloom | it's more fun to see it with reductions: |
| 15:30 | justin_smith | sdegutis: iterate maybe |
| 15:30 | bbloom | (let [dict {'dup (fn [[x & s] _] (conj s x x)) '* (fn [[x y & s] _] (conj s (* x y)))}] (reductions #((dict %2 conj) %1 %2) () '(5 dup *))) |
| 15:30 | bbloom | ,(let [dict {'dup (fn [[x & s] _] (conj s x x)) '* (fn [[x y & s] _] (conj s (* x y)))}] (reductions #((dict %2 conj) %1 %2) () '(5 dup *))) |
| 15:30 | clojurebot | (() (5) (5 5) (25)) |
| 15:30 | justin_smith | bbloom: yup, and that does exactly what the forth program "5 dup *" would do |
| 15:30 | sdegutis | Could this be easier with transducers maybe? |
| 15:30 | cbryan | ugh, "contact us about pricing." my four least favorite words |
| 15:30 | sdegutis | bbloom: That is just so cool. |
| 15:31 | justin_smith | haha, transducers are more about perf than ease of programming |
| 15:31 | sdegutis | Oh I didn't know that. |
| 15:31 | sdegutis | I am now tempted to embed a forth interpreter somewhere in our website. |
| 15:31 | Bronsa | justin_smith: perf & reusability |
| 15:31 | sdegutis | Yeah I thought reusability was the big one. |
| 15:31 | the_danko | TimMc: I don't feel like it is clicking with the (-> a #((((((a))))))) |
| 15:32 | the_danko | TimMc: if you're bored. otherwise i'll figure it out. thanks again. |
| 15:32 | TimMc | First see what the reader does. |
| 15:32 | TimMc | ,'(-> a #((((((a))))))) |
| 15:32 | clojurebot | (-> a (fn* [] ((((((a)))))))) |
| 15:32 | justin_smith | Bronsa: sdegutis: well, perf unless you are implementing something like core.async where you end up replicating things like map and filter on a new data source, then they do make things easier |
| 15:32 | TimMc | Then see what macroexpansion does: |
| 15:32 | melipone | hello! I would like to use the marmaduke common-math-3 library on clojars but I can't seem to find its github location. Do u know it? |
| 15:32 | TimMc | ,(macroexpand '(-> a #((((((a)))))))) |
| 15:32 | clojurebot | (fn* a [] ((((((a))))))) |
| 15:33 | TimMc | ,(macroexpand '(-> a #(a))) ;; a simpler version |
| 15:33 | clojurebot | (fn* a [] (a)) |
| 15:33 | justin_smith | melipone: you can get the source out of the jar if nothing else |
| 15:33 | clojurebot | Huh? |
| 15:33 | justin_smith | melipone: but you don't need the github location in order to use it if that's what you mean |
| 15:34 | TimMc | ,(-> a #(= (a) a)) |
| 15:34 | clojurebot | #<sandbox$eval133$a__134 sandbox$eval133$a__134@83c488> |
| 15:34 | TimMc | ,((-> a #(= (a) a))) |
| 15:34 | clojurebot | #<StackOverflowError java.lang.StackOverflowError> |
| 15:34 | TimMc | the_danko: Sorry, my example was bad. |
| 15:35 | TimMc | ,((-> a #(a))) |
| 15:35 | clojurebot | #<StackOverflowError java.lang.StackOverflowError> |
| 15:35 | the_danko | TimMc why are you using a for the function and the argument? |
| 15:35 | justin_smith | melipone: I think the actual source is linked here http://commons.apache.org/proper/commons-math/download_math.cgi |
| 15:35 | the_danko | TimMc is that part of the lesson? i assume so. i just don't get why. |
| 15:36 | TimMc | There's no argument, actually -- I'm just demonstrating that -> is capable of giving a function literal a name. A terrible idea, but interesting. |
| 15:37 | the_danko | TimMc interesting. i'll have to come back to this after a few more days of study it looks like. thanks for your help once more. |
| 15:37 | TimMc | (-> a (fn* [] ...)) becomes (fn* a [] ...); "a" doesn't end up in the body of the fn, because that's not the outermost collection. |
| 15:44 | melipone | justin_smith: But how do I know what is the clojure interface? |
| 15:44 | justin_smith | melipone: I don't know that there is on - but you can open the jar you get from clojars, it's a zip file |
| 15:44 | justin_smith | s/on/one |
| 15:48 | melipone | justin_smith: If there is no clojure wrapper, why is there a clojar package for it? |
| 15:49 | justin_smith | melipone: I am wondering what is up with that package, checking it out now |
| 15:51 | justin_smith | melipone: weird, when I specify the dep, it doesn't even seem to download anything.... |
| 15:53 | melipone | justin_smith: it did download something. I'm checking it out now |
| 15:53 | justin_smith | weird, seems like my emacs is misbehaving |
| 15:54 | melipone | justin_smith: yeah, it's just the apache jar and nothing else. |
| 15:54 | justin_smith | melipone: yeah, that was my first guess (I am seeing that now too) |
| 15:54 | justin_smith | my emacs dired for some reason showed me an empty directory the first time... problem on my end clearly |
| 16:20 | txgruppi | Hi. I am new to Clojure and ClojureScript. I can't find my answer on Google. Is it possible to sue ClojureScript without Clojure? I have a PHP REST API and I would like to use swannodette/om with it. Is it possible? |
| 16:21 | postpunkjustin | IANAL, but yes |
| 16:22 | postpunkjustin | ClojureScript just compiles to JavaScript, so it's not dependent on Clojure in any particular way |
| 16:22 | technomancy | the compiler is written in clojure, but that's all |
| 16:23 | justin_smith | txgruppi: a previous employer was able to put clojurescript in production without deploying any clojure |
| 16:23 | txgruppi | postpunkjustin, technomancy, justin_smith: So, I just need to create a clojure project because of the compiler and I can use the js output in my app, right? |
| 16:23 | justin_smith | right |
| 16:23 | postpunkjustin | Yeah, your output will be HTML+JS |
| 16:24 | txgruppi | postpunkjustin, technomancy, justin_smith: Thank you all |
| 16:24 | technomancy | txgruppi: my gut feeling is that practically speaking, you have to know clojure because the tools and docs for using cljs all assume you know it. |
| 16:24 | technomancy | even if it's theoretically not required. |
| 16:24 | justin_smith | technomancy: I assumed it was more about being able to use cljs in production without deploying clojure itself, I could have misinterpreted |
| 16:24 | txgruppi | technomancy: the problem is that I can't just change the backend to clojure. Learning clojure will not be a problem |
| 16:25 | technomancy | ok, cool |
| 16:26 | justin_smith | "Learning clojure will not be a problem." that's the spirit! |
| 16:27 | txgruppi | hauhuahuahua |
| 16:27 | teslanick | Do you have a chant or mantra that I can pass along to my coworkers? |
| 16:27 | amalloy | $timer 30 0 0 hauhuahuahua |
| 16:27 | lazybot | Timer added. |
| 16:28 | hiredman | ~suddenly |
| 16:28 | clojurebot | CLABANGO! |
| 16:28 | txgruppi | I am tired of PHP, I don't like ruby/python for web development, I don't use M$ stuff. Solution: Slowly migrate to Go, NodeJS, Clojure |
| 16:29 | justin_smith | txgruppi: a buddy of mine deploys cljs to backend node |
| 16:30 | txgruppi | justin_smith: nice! does he have any github (or some other public place) project with it? |
| 16:30 | justin_smith | txgruppi: I'll ask, and let him speak up if he would like to break anonymity :) |
| 16:31 | txgruppi | justin_smith: thx =D |
| 16:36 | postpunkjustin | I'm kind of puzzled by cljs+node on the backend. I mean, you're basically writing Clojure at that point, but you don't have real threads. |
| 16:36 | justin_smith | postpunkjustin: a client very picky about implementation, and not very wise about the tech, I think |
| 16:37 | arrdem | postpunkjustin: and you sacrifice access to all the JVM libraries and tooling. No, I agree. |
| 16:37 | postpunkjustin | Yeah, I can see how that would happen. |
| 16:37 | hiredman | it is a silly thing to do |
| 16:37 | technomancy | people do silly things all the time though |
| 16:38 | technomancy | https://en.wikipedia.org/wiki/The_Ministry_of_Silly_Walks |
| 16:38 | postpunkjustin | I actually thought about doing it for something that would run on a Raspberry Pi, since Clojure is a bit much for the hardware. |
| 16:39 | hiredman | don't get me started |
| 16:39 | justin_smith | postpunkjustin: I have a beablebone that runs a node webserver by default |
| 16:40 | justin_smith | for when you want to use a browser / html5 to push buttons on a screen in order to make an led on a device turn off and on |
| 16:40 | justin_smith | *beaglebone |
| 16:42 | postpunkjustin | Yeah, Node is way better than the JVM for serving something like that on "cute" hardware |
| 16:42 | postpunkjustin | esp. when the JVM has to load all of clojure.core |
| 16:42 | seangrove | postpunkjustin: Gotat go ocaml if that's where you're headed |
| 16:43 | hiredman | the jvm was designed for embedded set top boxes |
| 16:43 | technomancy | just use rackjure if you're low on ram =) |
| 16:44 | postpunkjustin | Woah, hadn't heard of rackjure, but I should have guessed it would happen sooner or later |
| 16:44 | postpunkjustin | I kind of like Hy |
| 16:44 | postpunkjustin | but I used to write a fair bit of Python |
| 16:44 | technomancy | hy... http://thisotplife.tumblr.com/post/63360807823/mutable-data-structures |
| 16:45 | postpunkjustin | Yeah, Clojure's immutable data structures are part of my brain now. |
| 16:48 | sdegutis | bbloom: I'd love to see a full-blown library expanded on your Forth interpreter tweets. That'd rock. |
| 16:49 | sdegutis | postpunkjustin: Yeah totally; whenever I write in Ruby it gets really awkward because I try to return stuff all the time, and just use functions, but Ruby doesn't make it easy. |
| 16:49 | postpunkjustin | Ugh Ruby. |
| 16:50 | sdegutis | postpunkjustin: You prefer Python? |
| 16:53 | postpunkjustin | Yeah, but only marginally at this point |
| 17:08 | toxmeister | hey guys, anyone know if clojar deploys are currently broken? am getting "403 forbidden Reason:passphrase" but nothing has changed on my GPG or SSH keys (just double checked) and I successfully deployed few weeks ago... |
| 17:10 | justin_smith | toxmeister: ssh upload is turned off, gpg only |
| 17:10 | hiredman | the scp deploy method was disabled due to, I think shellshock is what it is being called |
| 17:10 | hiredman | you have to use `lein deploy` which deploys via https |
| 17:11 | toxmeister | yes, using `lein deploy clojars` as usual |
| 17:11 | technomancy | 403 indicates that it's an http failure though |
| 17:11 | hiredman | Oh |
| 17:12 | technomancy | toxmeister: I'm getitng the same thing |
| 17:12 | technomancy | looking into it |
| 17:12 | toxmeister | weird, just tried once more the same... and it worked this time!! |
| 17:13 | toxmeister | technomancy: thanks, but use your time more wisely :) |
| 17:13 | technomancy | but it's still failing for me |
| 17:15 | justin_smith | toxmeister: technomancy: http://i.imgur.com/Y6hqNQP.png |
| 17:17 | toxmeister | technomancy: yeah, happening again for me too (there i was hoping to have a release friday...) |
| 17:17 | technomancy | xeqi: any changes to clojars recently? |
| 17:18 | toxmeister | technomancy: is there a way to get more verbose debug info for these deploy requests? |
| 17:18 | toxmeister | bit like `curl -v` |
| 17:19 | technomancy | toxmeister: you can try setting LEIN_DEBUG=y |
| 17:19 | technomancy | or maybe just DEBUG=y |
| 17:20 | technomancy | nothing all that helpful though |
| 17:23 | toxmeister | hmmm... looking at https://clojars.org/repo/thi/ng/geom-core/0.3.0-SNAPSHOT/ it seems to have copied the files though (last version 20141031.212027) |
| 17:24 | toxmeister | maybe that error can be ignored? |
| 17:24 | cfleming | the_danko: You can already align map items like that in Cursive: Settings->Code Style->Clojure->Align map items |
| 17:24 | xeqi | technomancy: nothing |
| 17:24 | xeqi | technomancy: theres some minor restructuring refactorings on master, but nothing has been deployed in months |
| 17:25 | cfleming | the_danko: Also, Settings->IDE->Clojure->Rainbow parens - the default colours are pretty subtle, you can configure them though. I'll be adding something more psychodelic at some point. |
| 17:25 | technomancy | logs are rather unhelpful for this |
| 17:26 | justin_smith | cfleming: double-rainbow-parans-what-does-it-mean |
| 17:26 | erikcw | I have a ClojureScript repl running in my terminal. I’ve connected to the repl process from emacs using cider-connect — however, I’m conntect in a Clojure context. How do I enter the ClojureScript repl from here? |
| 17:27 | the_danko | cfleming cfleming: awesome, thanks! |
| 17:27 | justin_smith | erikcw: which clojurescript repl do you have running? |
| 17:27 | xeqi | looks like maven-metadata.xml didn't get updated, wonder if url that being split wrong |
| 17:27 | the_danko | cfleming maybe the rainbow hsould be default? also i agree on the brigher colors. very helpful still. thanks. just turned them on |
| 17:27 | erikcw | justin_smith: with figwheel (using the chestnut lein template) |
| 17:28 | xeqi | not sure why that would have changed since aug tho |
| 17:28 | erikcw | justin_smith: weasle with figwheel — sorry |
| 17:29 | justin_smith | erikcw: you should be able to run M-x cider, and then pick the port that weasel is running on |
| 17:29 | justin_smith | cider-jack-in starts a process, cider just finds one to connect to |
| 17:29 | justin_smith | or maybe it is called cider-connect now |
| 17:30 | lambdahands | Is there a way to create a core.async timeout function that accepts microseconds instead of milliseconds? |
| 17:33 | amalloy | lambdahands: (fn [t] (timeout (quot t 1000))) |
| 17:33 | toxmeister | xeqi: you're right, the last update to maven-metadata.xml for my project was on aug 17, even though there're newer jars uploaded |
| 17:33 | amalloy | not a useful answer, i'm sure, but the best one available |
| 17:33 | erikcw | justin_smith: seems to just timeout if I connect to the weasel web socket port (9001). I am able connect to the main repl process that is running weasle though. Problem is, I have no idea how to get into the clojurescript prompt from there. I’m stuck in Clojure “user>” instead of Clojurescript “cljs.user>” |
| 17:33 | dbasch | amalloy: you could build your own with the high resolution timer |
| 17:34 | dbasch | who knows how accurate it would be |
| 17:35 | justin_smith | erikcw: have you tried the code suggested on the weasel readme? https://github.com/tomjakubowski/weasel |
| 17:35 | justin_smith | the whole (cemerick.piggieback/cljs-repl ...) thing |
| 17:36 | dbasch | ,(let [[a _ b] [(System/nanoTime) (Thread/sleep 1) (System/nanoTime)]] (- b a)) |
| 17:36 | clojurebot | 1144357 |
| 17:36 | dbasch | &(let [[a _ b] [(System/nanoTime) (Thread/sleep 1) (System/nanoTime)]] (- b a)) |
| 17:36 | lazybot | ⇒ 14949110 |
| 17:36 | erikcw | justin_smith: yeah — I get an “Address already in use” error |
| 17:36 | justin_smith | erikcw: when specify a different address? |
| 17:37 | justin_smith | *then |
| 17:37 | erikcw | justin_smith: I guess I’m not being clear. I’m trying to connect to the already running session. Perhaps that just isn’t suppored? |
| 17:38 | jcsims | erikcw: aside from the lack of a 'cljs.user' prompt, are you sure you're not in a cljs context when you connect? |
| 17:38 | justin_smith | erikcw: I am sorry, I don't know. |
| 17:39 | justin_smith | erikcw: so you opened a cljs context in a repl, and then when you connect to the repl in emacs you get clj? |
| 17:40 | badyl | hi, I would like to define a comparator for a set of keywords (or in other words define an order of a set of keywords) |
| 17:40 | erikcw | jcsims: Looks like you’re right — I am in a cljs context, I just didn’t know it! OOPS!! |
| 17:41 | arrdem | so.. an enum with keywords as values? |
| 17:41 | badyl | and I am wondering how it can be done in a most clear way |
| 17:41 | jcsims | erikcw: good! if that wasn't the case, I was out of suggestions ;) |
| 17:41 | justin_smith | badyl: you can use sorted-set-by, and any function that predictably returns -1 0 or 1 when provided with two keywords |
| 17:41 | erikcw | jcsims: I assumed they were running under different threads or something |
| 17:41 | erikcw | jcsims: thank you |
| 17:41 | erikcw | justin_smith: thank you! |
| 17:42 | badyl | arrdem: yes, I have maps where there is an entry with keyword values as enums |
| 17:42 | jcsims | erikcw: no problem! |
| 17:43 | arrdem | amalloy: so why are you not a fan of your own defenum macro? |
| 17:43 | justin_smith | ,(sorted-set-by (fn [a b] (compare (mod (int (first (name a))) 8) (mod (int (first (name b))) 8))) :a :b :c :d :e :f :g :h :i :j) |
| 17:43 | clojurebot | #{:h :a :b :c :d ...} |
| 17:43 | dbasch | keywords are comparable |
| 17:44 | dbasch | what’s wrong with the default (lexicographic) sort? |
| 17:44 | amalloy | arrdem: the one that's like the first project i ever pushed to github? |
| 17:44 | arrdem | amalloy: back in 2010 yeah that one |
| 17:45 | dbasch | ,(compare :a :b) |
| 17:45 | clojurebot | -1 |
| 17:45 | amalloy | arrdem: you want me to look further than https://github.com/amalloy/enum/blob/master/src/enum/core.clj#L3 ? |
| 17:45 | arrdem | maybe this isn't the _right_ defenum, but I think in principle a defenum is reasonable. |
| 17:45 | arrdem | amalloy: no need I'm wiping blood away too |
| 17:46 | badyl | let's say I have maps like {.... :type :a}, {..... :type :b} {.... :type :c} etc and I want them to be compared by :type key, but in my specific order, e.g. :c :a :b |
| 17:46 | justin_smith | dbasch: I am aware they are comparable, but I assumed he wanted some non-default sorting |
| 17:46 | badyl | I know I can use just (compare :a :b) but I need a specific order, not lexicographics one |
| 17:46 | justin_smith | badyl: then use sorted-set-by as I showed above, with a function that provides the right comparison result |
| 17:46 | dbasch | never mind, it wasn’t clear to me from the question |
| 17:46 | dbasch | but in that case yeah, just define your own compare function |
| 17:47 | lambdahands | @amalloy Thanks! So timeout takes a quoted list with two elements? |
| 17:47 | justin_smith | badyl: .indexOf on an array may help (subtracting two indexes to get pos / 0 / neg |
| 17:47 | justin_smith | |
| 17:47 | justin_smith | ) |
| 17:47 | badyl | dbasch: ok, I just thought there is a function that will create one when I provide a seq of my keywords in my specified order :) |
| 17:47 | amalloy | lambdahands: that quot is "quotient". it's a facetious suggestion that you divide microseconds by a thousand to get back to milliseconds |
| 17:47 | badyl | but it seems I have to write one |
| 17:48 | dbasch | lambdahands: do you need sub-millisecond resolution? I guess that’s the question |
| 17:48 | amalloy | because there's nothing i know of that takes microseconds, nor any compelling reason to need it |
| 17:48 | amalloy | badyl: https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L243 is kinda close |
| 17:49 | amalloy | you can't use it directly but you can perhaps adapt the idea |
| 17:49 | dbasch | &(let [[a _ b] [(System/nanoTime) (Thread/sleep 1) (System/nanoTime)]] (- b a)) |
| 17:49 | lazybot | ⇒ 18028774 |
| 17:49 | dbasch | that’s 18 ms |
| 17:49 | lambdahands | @amalloy: Ah, of course. |
| 17:50 | lambdahands | dbasch: Yes, that's what I'm looking for. |
| 17:50 | amalloy | &(let [[a _ b] [(System/nanoTime) (Thread/yield 1) (System/nanoTime)]] (- b a)) |
| 17:50 | lazybot | java.lang.IllegalArgumentException: No matching method: yield |
| 17:50 | amalloy | &(let [[a _ b] [(System/nanoTime) (Thread/yield) (System/nanoTime)]] (- b a)) |
| 17:50 | lazybot | ⇒ 15650228 |
| 17:50 | lambdahands | It's for a live performance using overtone's Open Sound Control library. |
| 17:50 | amalloy | &(let [[a _ b] [(System/nanoTime) [] (System/nanoTime)]] (- b a)) |
| 17:50 | lazybot | ⇒ 8380435 |
| 17:51 | badyl | amalloy: thanks it is really close |
| 17:51 | badyl | justin_smith: your solutions is also similar |
| 17:51 | dbasch | ,(let [[a b] [(System/nanoTime) (System/nanoTime)]] (- b a)) |
| 17:51 | clojurebot | 12407 |
| 17:52 | dbasch | &(let [[a b] [(System/nanoTime) (System/nanoTime)]] (- b a)) |
| 17:52 | lazybot | ⇒ 7417257 |
| 17:52 | badyl | thanks guys for the ideas. It's my first interaction with clojurians on IRC and you were very helpful |
| 17:52 | dbasch | does lazybot run on an abacus? |
| 17:52 | justin_smith | badyl: thanks |
| 17:53 | dbasch | , (- (System/nanoTime) (System/nanoTime)) |
| 17:53 | clojurebot | -818 |
| 17:53 | dbasch | & (- (System/nanoTime) (System/nanoTime)) |
| 17:53 | lazybot | ⇒ -7569558 |
| 17:53 | lambdahands | Hmm, so System/nanoTime is the answer then? |
| 17:53 | justin_smith | ,(let [order [:c :b :a]] (- (.indexOf order :b) (.indexOf order :a))) |
| 17:53 | clojurebot | -1 |
| 17:54 | justin_smith | badyl: the above could be easily made a comparison function, with your order of keys specified in a vector |
| 17:54 | EvanR | is there a function to convert keyword to string without the prefixed : |
| 17:54 | justin_smith | EvanR: name |
| 17:54 | justin_smith | ,(name :a) |
| 17:54 | clojurebot | "a" |
| 17:55 | justin_smith | ,(map name ['a "a" :a]) |
| 17:55 | clojurebot | ("a" "a" "a") |
| 17:55 | justin_smith | I like the above :) |
| 18:05 | amalloy | dbasch: lazybot has some weird stuff in its interop-sandboxing code |
| 18:06 | amalloy | i don't remember what the deal is anymore, but it makes interop really slow |
| 18:06 | dbasch | amalloy: is it sending everything to the NSA? :P |
| 18:06 | arrdem | dbasch: this is IRC they get everything anyway |
| 18:07 | dbasch | arrdem: you can be lazy and paranoid :P |
| 18:33 | amalloy | is there some version of max that uses compare instead of >? |
| 18:34 | hiredman | ,(doc max-key) |
| 18:34 | clojurebot | "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest." |
| 18:34 | hiredman | sort of |
| 18:35 | amalloy | right, which doesn't actually do that. it's fine if you can map your stuff onto integers |
| 18:35 | hiredman | ,(doc compare) |
| 18:35 | clojurebot | "([x y]); Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than', 'equal to', or 'greater than' y. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable" |
| 18:35 | hiredman | isn't that would compare does? |
| 18:35 | hiredman | what |
| 18:36 | hiredman | Oh |
| 18:36 | hiredman | right |
| 18:37 | hiredman | well, wait, I think that should be fine |
| 18:37 | TEttinger | (doc sort) |
| 18:37 | clojurebot | "([coll] [comp coll]); Returns a sorted sequence of the items in coll. If no comparator is supplied, uses compare. comparator must implement java.util.Comparator. If coll is a Java array, it will be modified. To avoid this, sort a copy of the array." |
| 18:38 | TEttinger | so sort and get the last? |
| 18:38 | hiredman | max works are two arguments, so you don't need everything mapped to some known fixed set of numbers, it should work |
| 18:38 | hiredman | (unless max-key just calls the key once) |
| 18:38 | hiredman | on two |
| 18:38 | hiredman | you just need to be able to come with numbers for every two things, not for everthing |
| 18:39 | amalloy | hiredman: i don't understand. max-key calls (f x) and (f y), then compares them |
| 18:39 | amalloy | it doesn't call (f x y), which would be the compare interface, and exactly what i wanted |
| 18:39 | hiredman | foo, right |
| 18:40 | hiredman | I was not thinking about compare correctly of course |
| 18:41 | amalloy | i'm pretty sure that at some point in the past i told someone they were silly for wanting this max-by thing i'm asking for |
| 18:42 | TEttinger | amalloy, because you can sort and get the first or last? |
| 18:42 | amalloy | TEttinger: no, that is outrageous |
| 18:42 | amalloy | performing an O(n*log(n)) operation for no reason when O(n) will do is not something you should do |
| 18:42 | TEttinger | fine |
| 18:44 | amalloy | i probably argued the opposite reason: that it's not very fast to keep doing this expensive compare operation on pairs of elements, so clojure doesn't encourage it, or something like that |
| 18:44 | amalloy | that sounds like me |
| 18:44 | dbasch | amalloy: one more thing you can stick in useful |
| 18:45 | TEttinger | (doc compare) |
| 18:45 | clojurebot | "([x y]); Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than', 'equal to', or 'greater than' y. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable" |
| 18:46 | dbasch | something like |
| 18:46 | dbasch | (defn max-by [f a b] (if (pos? (f a b)) a b)) |
| 18:47 | dbasch | and reduce by that, or whatever |
| 18:48 | TEttinger | ,(defn max-compare [coll] (reduce #(if (pos? (compare %1 %2)) %1 %2) coll)) |
| 18:48 | clojurebot | #'sandbox/max-compare |
| 18:49 | TEttinger | ,(max-compare [2 3 [1 2 3 4]]) |
| 18:49 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 18:49 | TEttinger | well I dunno how that works |
| 18:51 | hyPiRion | ,(compare 3 [1 2 3 4]) |
| 18:51 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 18:51 | TEttinger | type-independent manner my ass |
| 18:53 | hyPiRion | compares numbers and collections in a type-independent manner => ints and doubles can be compared, lists and vectors can be compared |
| 18:54 | hyPiRion | It's not like comparing a number to a collection suddenly made sense. |
| 18:54 | technomancy | eeeeeh |
| 18:54 | technomancy | I can see value in a universal comparator |
| 18:55 | technomancy | it doesn't have to make sense across types so much as be consistent across types |
| 18:58 | andonilsson | Weird thing. Was using core.async channels for dealing with cards (you know, poker etc). So I tried: (onto-chan (chan) deck-of-cards) |
| 18:58 | andonilsson | ...but the channel returned from onto-chan never contained anything. |
| 18:59 | andonilsson | Instead I had to do something like: |
| 18:59 | andonilsson | (def c (chan)) |
| 18:59 | andonilsson | (onto-chan c deck-of-cards) |
| 18:59 | andonilsson | ...and then I could pull my cards from channel c. |
| 19:04 | nathan7 | andonilsson: (doto (chan) (onto-chan deck-of-cards))? |
| 19:04 | nathan7 | ,(macroexpand `(doto (chan) (onto-chan deck-of-cards))) |
| 19:04 | clojurebot | (let* [G__27 (sandbox/chan)] (sandbox/onto-chan G__27 sandbox/deck-of-cards) G__27) |
| 19:04 | nathan7 | shit, I gotta go refactor a whole lot of code using that trick |
| 19:04 | andonilsson | or, even better in my case: (to-chan deck-of-cards) |
| 19:05 | andonilsson | Found it while browsing the source for onto-chan |
| 19:06 | justin_smith | yeah, doto is kind of handy sometimes |
| 19:07 | JohnJJ | hi guys I want to add the JDBC jar to a local repository, I've tried Archivia without success, what do u suggest? |
| 19:07 | andonilsson | still, I find it weird that the channel returned from onto-chan is not of any use. Instead I have to use the 'original' channel (the one passed into onto-chan) |
| 19:07 | justin_smith | JohnJJ: how are you managing your deps? if it is not lein you should probably switch. |
| 19:08 | technomancy | JohnJJ: depends on why you want a local repository, really. lots of ways to do it. |
| 19:08 | JohnJJ | justin_smith, technomancy: I'm using lein, and I'm using Nightcode as an IDE |
| 19:09 | justin_smith | JohnJJ: and using the usual .m2/ cache doesn't suffice for local repository? |
| 19:09 | justin_smith | are you serving a dep for multiple users or machines? |
| 19:10 | JohnJJ | justin_smith: I've just tried that but couldn't get how the folder structure should be, can I just put the .jar there? |
| 19:10 | technomancy | JohnJJ: what are you trying to accomplish? |
| 19:10 | technomancy | usually archiva is used to cache dependencies to protect against network failures and stuff |
| 19:10 | justin_smith | JohnJJ: the normal thing is to declare the dep, such that lein finds it automatically |
| 19:11 | technomancy | or for private stuff, not jdbc drivers |
| 19:11 | JohnJJ | technomancy: just trying to get my clojure app to connect to SQL Server |
| 19:11 | justin_smith | JohnJJ: add [mysql/mysql-connector-java "5.1.6"] to your deps in project.clj |
| 19:12 | justin_smith | and you probably want org.clojure/java.jdbc too |
| 19:12 | justin_smith | oh way you didn't say mysql |
| 19:12 | JohnJJ | justin_smith: it is SQL Server from Microsoft, not Mysql |
| 19:13 | justin_smith | http://claude.betancourt.us/add-microsoft-sql-jdbc-driver-to-maven/ install it locally, then declare a dep |
| 19:13 | JohnJJ | justin_smith: I've lein installed but not maven, should I install maven then? |
| 19:14 | justin_smith | JohnJJ: technomancy: there is a lein command for that, right? |
| 19:14 | technomancy | yeah, check out the second arity of deploy |
| 19:14 | JohnJJ | justin_smith: that's my confusion, how can lein run without maven |
| 19:15 | justin_smith | JohnJJ: it uses a bunch of the same libs |
| 19:17 | justin_smith | technomancy: I'm looking at lein help deploy now - what is the magic repo string for "into .m2" |
| 19:17 | technomancy | justin_smith: file:///home/me/.m2/repository |
| 19:17 | justin_smith | technomancy: cool |
| 19:18 | justin_smith | JohnJJ: so that's the simplest way (other than installing maven and copy/paste from that web site I guess) |
| 19:20 | JohnJJ | justin_smith, technomancy: I'm trying to install maven right now |
| 19:26 | technomancy | wow, so the MS DB honestly does not publish any official jdbc deps? |
| 19:27 | justin_smith | technomancy: all I could find were workarounds via local install |
| 19:27 | technomancy | inconcievable |
| 19:28 | mlb- | In SKI combinator calculus, is the Clojure `doto` macro analagous to the K combinator? |
| 19:28 | technomancy | mlb-: not really, SKI doesn't have side-effects |
| 19:29 | technomancy | I would say K is more like constantly |
| 19:29 | mlb- | ah, that's fair |
| 19:29 | technomancy | but neither functions nor macros map strictly to combinators I guess |
| 19:30 | justin_smith | technomancy: JohnJJ: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/db43206a-756c-4291-9c67-e813d18bdbf5/can-microsoft-please-publish-the-jdbc-driver-for-sql-server-on-maven-central?forum=sqldataaccess |
| 19:30 | mlb- | I ask because I've recently been abusing `doto` inside of thread first/last macros |
| 19:30 | amalloy | mlb-: how is that abuse? doto and -> go together like bacon and eggs |
| 19:30 | justin_smith | mlb-: doto inside thread-last seems a bad plan |
| 19:30 | amalloy | it's a lot harder in ->> |
| 19:31 | justin_smith | now if we had doneby |
| 19:31 | justin_smith | (which would be like doto but taking the thing as the last arg) |
| 19:31 | JohnJJ | justin_smith: sad MS is sad, I'm progressing with Maven right now |
| 19:31 | justin_smith | JohnJJ: cool |
| 19:32 | mlb- | I've been doing things like (->> stuff (map transform) (filter predicate?) (#(doto % (->> count (spy :info "Count of stuff"))))) |
| 19:32 | justin_smith | mlb-: aha - as-> may help there |
| 19:33 | mlb- | and then continuing the chain, unaffected by the doto's transformation on the collection |
| 19:33 | technomancy | (doto prn) in -> is the best |
| 19:33 | justin_smith | yes it is |
| 19:33 | Bronsa | true |
| 19:34 | mlb- | I'm using a slightly more verbose syntax with timbre's spy to help my coworkers who aren't used to thread-last chains across collections |
| 19:36 | mlb- | thanks for the reassurance, everyone =] |
| 20:11 | whodidthis | whats an easy way to forward all messages from one channel to another |
| 20:13 | justin_smith | whodidthis: looks like that is what pipe does |
| 20:13 | whodidthis | oh cool |
| 21:18 | wei | i have a long sequence of numbers, and i want the sum at the end as well as the max value that the sum ever took. what’s the best way to get these two values without having to go through the sequence twice? |
| 21:21 | justin_smith | ,(reduce (fn [[mx sum] v] (let [update (+ v sum)] [(max update mx) update])) [0 0] [1 2 -30 8 12]) |
| 21:21 | clojurebot | [3 -7] |
| 21:22 | justin_smith | ,(reductions (fn [[mx sum] v] (let [update (+ v sum)] [(max update mx) update])) [0 0] [1 2 -30 8 12]) ; for good measure |
| 21:22 | clojurebot | ([0 0] [1 1] [3 3] [3 -27] [3 -19] ...) |
| 21:22 | andrewhr | that was fast :O |
| 21:22 | andrewhr | I was just tinkering on repl… |
| 21:23 | justin_smith | andrewhr: it took me a few tries |
| 21:24 | andrewhr | hahaha ok. I will keep up practing my clojure-fu |
| 21:24 | muraiki_ | you could also use http://clojuredocs.org/clojure.core/reductions |
| 21:24 | justin_smith | muraiki_: see my second example |
| 21:24 | muraiki_ | oh |
| 21:24 | muraiki_ | haha |
| 21:24 | muraiki_ | didn't read that far yet T_T |
| 21:25 | justin_smith | well I didn't use reductions to find the max - simpler to just update in one pass |
| 21:25 | justin_smith | though I could have used reductions of sum, and taken the max of that |
| 21:25 | muraiki_ | yeah, that's the approach I was thinking of |
| 21:25 | muraiki_ | my clojure-fu is weak though |
| 21:25 | andrewhr | same approach here |
| 21:26 | justin_smith | ,((juxt #(apply max %) last) (reductions + 0 [1 2 -30 8 12])) |
| 21:26 | clojurebot | [3 -7] |
| 21:26 | justin_smith | actually the reductions / max version is elegant |
| 21:26 | justin_smith | but does an extra walk, which is against the first criteria :) |
| 21:26 | justin_smith | actually it walks the full length 3 times |
| 21:29 | hyPiRion | speaking of, is there anyone else besides me finding a function à la this useful? |
| 21:29 | hyPiRion | ,(defn aside [& fs] (fn [vs x] (mapv #(%1 %2 x) fs vs))) |
| 21:29 | clojurebot | #'sandbox/aside |
| 21:29 | hyPiRion | ,(reduce (aside + - max) [0 0 0] (range 10)) |
| 21:29 | clojurebot | [45 -45 9] |
| 21:30 | justin_smith | oh, very nice |
| 21:31 | justin_smith | it captures a pattern I often do, where I want to do more than one reduction on the same sequence |
| 21:31 | hyPiRion | yeah, I tend to do that a lot too – It's like juxt on reductions |
| 21:32 | wei | thanks guys. so my sequence of numbers is the result of a transduce |
| 21:32 | wei | is there any benefit to writing the reduction as the final transduce step? |
| 21:33 | wei | and is that even possible? |
| 21:33 | justin_smith | in that case, you should be able to compose the other ops with the transduce |