#clojure log - Oct 31 2014

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:00 TimMc: I may have found it by searching for "clojure jobs", not really sure.

0:05 cfleming: In my macroexpanded code, I'm occasionally seeing vars like G__1234 - does anyone know when the compiler inserts those?

0:06 I've looked at all the uses of RT.nextID() and I can't figure it out.

0:06 justin_smith: ,(gensym)

0:06 clojurebot: G__27

0:06 cfleming: Aha, thanks.

0:06 Shows how many macros I write.

0:06 justin_smith: cfleming: they are in the reader for ` when you name something binding#

0:07 ,`(let [foo# 1] foo#)

0:07 clojurebot: (clojure.core/let [foo__50__auto__ 1] foo__50__auto__)

0:07 cfleming: justin_smith: Those are named <name>__1234__auto__, right?

0:07 justin_smith: ahh, right

0:07 so the others are manual genzyms

0:07 *gensyms

0:07 cfleming: justin_smith: The implicit parameters from a #() are p<num>__1234#

0:08 justin_smith: ,'#(%)

0:08 clojurebot: (fn* [p1__75#] (p1__75#))

0:08 justin_smith: yeah

0:08 cfleming: Ok, makes sense - those must be named in clojure.core - I'll take a look.

0:08 justin_smith: ,(gensym "foo")

0:08 clojurebot: foo102

0:09 cfleming: Ew

0:09 So that one sucks

0:09 justin_smith: I think it is fairly rare...

0:09 cfleming: All this is for detecting the changed region in the macroexpander I'm working on.

0:10 justin_smith: ahh, right, of course

0:11 cfleming: Some of these are stable across expansions, but some of them are generated every time (G__1234 and pn__1234#)

0:11 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.

0:12 justin_smith: cfleming: what about a placeholder for the number part?

0:12 yeah

0:12 and not strictly a suffic, thanks to # being there sometimes of course

0: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.

0:14 Fortunately there's only a couple of patterns.

0:16 Thanks!

0: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?

0: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

0:44 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

0:45 razum2um: justin_smith: is it really needed only as "syntactic sugar"?

0:45 only to reduce file count?

0: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

0:48 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.

0:49 mindbender1: is there a function I can use to output the bit representation of a number in 1s and 0s?

0:49 justin_smith: mindbender1: I think there is something in cl-format that can do that

0: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?

0:50 justin_smith: ,(require '[clojure.pprint :as pprint])

0:50 clojurebot: nil

0:50 justin_smith: ,(pprint/cl-format "~1r" 88)

0:50 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

0:51 justin_smith: ,(pprint/cl-format nil "~1r" 88)

0:51 clojurebot: eval service is offline

0:52 justin_smith: razum2um: tangent - when using the term "business logic" - what is the distinction, what part of the code is not business logic?

0:54 mindbender1: justin_smith: I'm trying to read up the docs

0: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.

0:54 razum2um: hm, say "valid user should have name and email" - (defn valid_user? [u] (every? some? ((juxt :email :name) u))))

0:55 mindbender1: justin_smith: see http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/clm/node199.html

0:55 justin_smith: ,(pprint/cl-format nil "~b" 88) ; mindbender1

0:55 clojurebot: "1011000"

0:55 mindbender1: ok

0:55 justin_smith: mindbender1: I don't mean the format function in common lisp - the clojure function called cl-format

0:56 razum2um: justin_smith: perhaps in practice you're right and i need to write more cljs %)

0:56 mindbender1: justin_smith: yeah. The docstring points there.

0: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

0:56 mindbender1: okay

0:56 thanks for clarifying

0: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

0: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?

0:58 justin_smith: razum2um: my previous employer, who I now do some contracting for, has some cljs code

0:59 razum2um: for example here http://www.onenorthpdx.com/

1:10 mindbender1: justin_smith: can't cl-format output hex as well?

1:10 can

1:10 justin_smith: ,(pprint/cl-format nil "~x" 99999)

1:10 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: pprint, compiling:(NO_SOURCE_PATH:0:0)>

1:11 justin_smith: ,(clojure.pprint/cl-format nil "~x" 99999)

1:11 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint>

1:11 justin_smith: ,(require '[clojure.pprint :as pprint])

1:11 clojurebot: nil

1:11 justin_smith: ,(pprint/cl-format nil "~x" 99999)

1:11 clojurebot: "1869f"

1:12 justin_smith: ,(pprint/cl-format nil "~x" 16rdeadbeef)

1:12 clojurebot: "deadbeef"

1:12 justin_smith: ,16rdeadbeef

1:12 clojurebot: 3735928559

1:13 mindbender1: okay. thanks

1:43 ,(pprint/cl-format nil "~2,8,'0r" x)

1:43 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: pprint, compiling:(NO_SOURCE_PATH:0:0)>

1:44 mindbender1: ,(require '[clojure.pprint :as pprint])

1:44 clojurebot: nil

1:44 justin_smith: x is still unbound

1:44 mindbender1: ,(pprint/cl-format nil "~2,8,'0r" 5)

1:44 clojurebot: "00000101"

1:44 mindbender1: just wanted to say thanks

1:44 justin_smith: np

1:54 marshall_: hey clojure

1:54 justin_smith: hello

1: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

1:55 is it something simple that i just don't understand? syntax maybe?

1: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)

1:57 :access-control-allow-methods [:post]

1:57 that part

1:57 oh!

1:58 marshall_: TEttinger: yeah, that's the part that clojure was complaining about

1:59 i just pasted from here: https://github.com/r0man/ring-cors

1: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)

1:59 marshall_: i only want to allow the POST method, so I removed the other methods from that part

2:01 TEttinger: oh, gotcha

2:01 it has to do with ->

2:01 justin_smith: marshall_: take out app-routes

2:01 from the wrap-cors call

2:01 it throws off the hash-map construction

2: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

2:03 ,(-> 100 (+ 10 10) (/ 12))

2:03 clojurebot: 10

2: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

2:04 fairuz: ,(->> 100 (+ 10 10) (/ 12))

2:04 clojurebot: 1/10

2:04 TEttinger: and ->> does the same thing with the thread inserting in the last argument position

2:05 marshall_: ok

2: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

2:06 marshall_: ahh I see

2:06 that's a handy feature

2:06 TEttinger: quite!

2:07 marshall_: i think they call that a currying function in javascript

2:07 or i guess in most other languages

2:09 TEttinger: kinda, -> actually works a bit differently. we have currying in the form of a function that returns functions, called partial

2:09 (doc partial)

2: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."

2:10 TEttinger: ,(map (partial + 10) [1 2 3])

2:10 clojurebot: (11 12 13)

2:10 marshall_: hmm

2:10 awesome

2:10 TEttinger: map I think is called map in javascript?

2:11 map, apply, filter are some of the most commonly used functions in clojure

2: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

2:11 TEttinger: yep

2:11 here, it returns a new collection, with state possibly shared

2:11 that's just an optimization clojure does

2:12 marshall_: [1,2,3].map(function(num){ return num +1 }) // >> [2,3,4]

2:12 i removed the app-routes parameter

2:12 but now I get a 404 for my one route

2:13 could it be the order of my middleware?

2: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

2:13 uh, I am not familiar with ring

2:14 marshall_: hmm

2:14 TEttinger: it looks like wrap-cors returns something that expects one arg?

2:14 https://github.com/r0man/ring-cors/blob/master/src/ring/middleware/cors.clj#L67

2:17 marshall_: what's clojure really good for? what do you use it for?

2:17 i'm coming from python and node.js

2:17 javascript

2:19 justin_smith: marshall_: it makes concurrency sane, and once you "get it", it helps facilitate a programming style that eliminates incidental complexity

2:19 shane1: It's jvm based, so I use it for doing functional programming with interop with java

2:19 justin_smith: marshall_: part of that is the idioms / supplied libs, but things like immutibility really help with that

2:20 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

2:23 marshall_: justin_smith: ahh i see

2:23 shane1, justin_smith: thanks

2: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.

2:27 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

2:29 marshall_: interesting

2:30 anybody have experience with ring? I'm trying to use CORS middleware

2:30 justin_smith: yes, I use ring all the time

2:33 marshall_: justin_smith: what am I doing wrong here? https://gist.github.com/jeffmarshall/b85a3f5fa6fe0e307112

2:33 i only have one route and it gives me a 404 now that I've included the cors middleware

2: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?

2:35 marshall_: hmm

2:35 ok

2:37 justin_smith: marshall_: I am not sure because I don't know that middleware though

2:38 marshall_: justin_smith: have you ever done anything in ring with CORS?

2:41 justin_smith: marshall_: no I have not

2:47 marshall_: justin_smith: dang

2: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

2:48 or is it visa versa? no matter

2:56 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

4: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?

5: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?

5:42 e.g. changing strings inside a defroutes macro do not update using standalone, but do in lein

5:43 looking at the sources I couldn't find a real difference between how they handle things

5: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

5:55 errr. function implementation instead of code.

5:56 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

6:06 vyvup: clgv: see ix.io/eZp for handler code

6:06 the repl commands that i use are there inside comments

6:07 clgv: I am sorry but don't quite understand what you mean

6:08 clgv: vyvup: change your startup to (def server (ring.server.standalone/serve #'clojure-testapp.core.handler/app))

6:08 vyvup: ok, will try

6:08 clgv: vyvup: this way you have an indirection through the variable and get the latest changes

6:09 vyvup: you know about refheap.com ?

6:09 vyvup: nope, but now i do :)

6:12 hmm, still does not work: what does the #' combination do?

6:12 TEttinger: ##(clojure.string/join ", " (range 500))

6: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

6:13 TEttinger: neat feature of lazybot is the automatic link to refheap for long printed returns

6:13 vyvup: clgv: the namespace is reloaded: the do-bye function to return another string it updates correctly

6:13 TEttinger: vyvup: it's the var-quote , it's documented at the clojure site but there's another guide out there

6:14 http://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/

6:14 clgv: TEttinger: haha great

6:14 TEttinger: it's a great guide

6:14 vyvup: TEttinger: ah, nice :)

6:15 clgv: vyvup: yeah, it should reload your routes assigned to the variable "app"

6:15 vyvup: yes, but it also did that without the #'

6:15 clgv: vyvup: do you reload the namespace where "app" is defined or just reevaluate the definition of "app"?

6:16 vyvup: didn't you say your routes were not updated?

6:16 vyvup: I depend on the reload behavior of (serve)

6:17 clgv: if `serve` is not a macro you should pass the variable `app`

6: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

6:18 clgv: vyvup: yes, that is because you do not use the var ;)

6:18 vyvup: hmm, but when I do use the var it also does not work

6:18 clgv: vyvup: you have to pass the var and you need to reevaluate the whole namespace or: first `app-routes` and then `app`

6:20 vyvup: ah, it seems I screwed up something else :)

6:23 clgv: yay, works \o/ thanks! I will read up on the macro stuff

6:28 TEttinger: (inc clgv)

6:28 lazybot: ⇒ 32

6:47 clgv: thanks

7:01 luxbock: is it just me or has the syntax hilighting for Clojure code at Github got significantly worse?

7: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?

7:05 (let [path (temp-file)] (with-open [output (output-thing path)] (let [obj (Obj. output)] ...

7:05 i need to return path, so i can't just inline it

7: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

7:31 raspasov: SagiCZ1: do you have specific example in mind?

7:33 borkdude: SagiCZ1 of course you care, but you usually know what you're dealing with

7:33 SagiCZ1: when i call (last (conj coll)) for example..

7:33 borkdude: no i dont.. some clojure functions return random weird types how am i supposed to know what they return

7:34 borkdude: SagiCZ1 they don't return random types. most sequence functions return lazy sequences

7:34 SagiCZ1: for example take-last returns PersistentVector, or PersistentVector$ChunkedSeq, or clojure.lang.Cons depending on the constellation of stars i guess

7:34 clgv: luxbock: it's just you. the colors and fonts change afaik

7:34 borkdude: ,(doc take-last)

7: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."

7:34 borkdude: It returns a seq.

7:35 SagiCZ1: ,(type (take-last 2 [5 4 3 2 0]))

7:35 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

7:35 SagiCZ1: looks like PersistentVector$ChunkedSeq to me

7:35 borkdude: (conj (take-last 2 [1 2 3]) 0)

7:35 ,(conj (take-last 2 [1 2 3]) 0)

7:35 clojurebot: (0 2 3)

7:35 borkdude: that's perfectly predicable

7:35 SagiCZ1 yes, PersistentVector.....Seq <- seq

7:35 clgv: SagiCZ1: that is a Seq just an implementation detail which class provides the seq methods ;)

7:35 SagiCZ1: but why does it return java.lang.Cons sometimes?

7:36 i mean clojure.lang.Cons

7: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

7:36 borkdude: ,(type (list 0))

7:36 clojurebot: clojure.lang.PersistentList

7:36 borkdude: ,(type (list))

7:36 clojurebot: clojure.lang.PersistentList$EmptyList

7:36 clgv: &(-> clojure.lang.Cons ancestors)

7: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}

7:36 borkdude: SagiCZ1 I don't even remember what returns a Cons, and I work with clojure pretty much every day

7:36 SagiCZ1 not important

7:37 clgv: SagiCZ1: cons ia a seq as well as you can see above ;)

7: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

7:37 clgv: borkdude: not-so-lazy lazy functions do that sometimes, because there impl starts with `cons` instead of `lazy-seq`

7: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

7:38 borkdude: yes, and if you really want to keep it strict, use mapv, filterv or transducers

7:38 clgv: SagiCZ1: you mean two time take-last?

7:38 SagiCZ1: the problem is take-last returns a seq and does not preserve the type vector

7:39 raspasov: SagiCZ1: use subvec for vectors

7:39 SagiCZ1: clgv: isnt that what i am talking about?

7:39 clgv: SagiCZ1: you could also implement as special take-last via sub-vec

7:39 borkdude: ,(vec (take-last 2 (range 10))

7:39 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

7:39 raspasov: https://clojuredocs.org/clojure.core/subvec

7:39 borkdude: ,(vec (take-last 2 (range 10)))

7:39 clgv: SagiCZ1: no. because take-last always returns seq and you talk about alternating return types

7:39 clojurebot: [8 9]

7:39 raspasov: use subvec, it's guaranteed O(1)

7:40 clgv: splitting hairs: take-last is O(1) as well - just not the realization part ;)

7:40 borkdude: use sequence functions and don't care about concrete types, until you expose them. premature optimization if you do I think

7:40 SagiCZ1: clgv: but sometimes it returns PersistentVector$chunkedSeq and sometimes clojure.lang.Cons .. andi guess my program depends on it for some reason

7:40 clgv: SagiCZ1: both are seqs just different implementations

7:40 Bronsa: SagiCZ1: those two types behave the same way unless you are explicitely testing for instanceness

7:41 clgv: no it does not. it might depend on the fact that you assume a vector where you get a sequence

7:41 SagiCZ1: ok thanks.. there is some super weird bug then.. i guess im just going crazy

7:41 Bronsa: SagiCZ1: when clojure talks about returning a seq, it means it will return an object whose type implements ISeq

7:41 no concrete type is guaranteed

7:41 raspasov: SagiCZ1: again, feel free to post a larger gist, we might be able to suggest something better

7:41 SagiCZ1: i use the return type in these functions:

7:41 apply, count, nth, last

7:41 shouldnt all these work fine for both types?

7:43 raspasov: it gets subtle, for example nth on a sequence is O(N) https://clojuredocs.org/clojure.core/nth

7:43 for some details I recommend https://www.youtube.com/watch?v=iQwQXVM6oiY

7:43 Bronsa: SagiCZ1: yes, they should. can you paste a gist with the code that you're talking about as the other suggested?

7:44 SagiCZ1: Bronsa: its spread through some files, i will look into it more and then construct some minimal example

7:45 Bronsa: SagiCZ1: early on you said that take-last returns a PersistentVector, that's never the case by the way.

7:49 SagiCZ1: ,(type (take-last 3 [2 0])

7:49 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

7:49 SagiCZ1: ,(type (take-last 3 [2 0]))

7:49 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

7:49 SagiCZ1: Bronsa: ok i guess i get confused.. im trying to solve this bug for about 5 hours now..

7:56 clgv: SagiCZ1: build small composable functions, test these individually

9: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

9:22 hyPiRion: si14: different Datomic versions – I don't think lein would check if the version is already there

9:22 si14: you don't have to use lein deps anymore though, fyi

9:24 si14: hyPiRion: yeah, lein repl also fails :) versions are same

9:25 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

9:25 * si14 am I right that .jar should be there?

9:25 hyPiRion: si14: yes

9:26 si14: hyPiRion: looks like a maven/Datomic bug then, because mvn build finishes without errors

9: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.

9: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

9:32 you need to remove ~/.m2/repository/com/datomic manually first

9:37 TimMc: hyPiRion: I superstitiously run `lein do clean, deps, compile, javac, midje, junit, uberjar` when I build.

9:39 hyPiRion: TimMc: Let's :prep-task ourself?

9:40 sounds reasonable.

9:41 fairuz: anyone use Titanium here?

9:42 csd_: anyone around that hosts on heroku?

9:43 daniel__: my laptop has some titanium in it

9:43 fairuz: daniel_ :)

9:46 clgv: ~anybody

9: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 ..."

9:47 csd_: :)

9:47 my sql server connection seems to be timing out on heroku. i'm wondering what the best way to fix it is.

9:47 happens after like 30 or so minutes of inactivity

9:48 TimMc: I don't think Heroku supports persistent connections like that.

9: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

9: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")?

9:49 err, :not-x in the second example

9:49 TimMc: csd_: Wait, Korma relies on a persistent connection? What do you mean by timing out, exactly?

9:49 jonathanj: ,(if-let [{x :x} {:not-x 5}] x "nope")

9:50 clojurebot: nil

9:50 jonathanj: ,(if-let [x (:x {:not-x 5})] x "nope")

9:50 clojurebot: "nope"

9: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.

9:50 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.

9: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?

9:55 csd_: I suppose I could have my app do something like SELECT 1 every 5 minutes. I think that might work.

9:58 xeqi: jonathanj: the if portion is checking against {x :x}. This will always be truthy. Destructuring doesn't effect the if portion

9:58 jonathanj: xeqi: ah, okay

9:59 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 (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 or something else with clojure syntax highlighting and without tons of ads ;)

10:15 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 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 xemdetia: looks fine to me. could be improved with some->

10:18 jonathanj: ^^

10:18 xemdetia: clgv, yes- employer is and it just gets flagged as possibly malicious

10:18 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 jonathanj: you could also pull `page` in a local scope within a `let` surrounding the `cond->`

10:22 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 *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 oh, i see, it's in the containing let

10:27 clgv: yeah exactly

10:27 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 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 i'm enhancing what was my first ever clojure application

10:34 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 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 but i'll take a look at refactoring once i'm done implementing the enhancement

10:41 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 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 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 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 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 zoom__: uhh

11:14 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 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 but really, forking isn't so bad when you've got an application to ship

11:19 csd_: well i don

11:19 dont

11:19 this is more just for fun

11:20 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 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 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 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 and sql sucks

11:28 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 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 ,(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 ,(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 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 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 ,(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 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 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 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 FIFO

12:34 SagiCZ1: yeah.. FIFO

12:34 5 came first so it gets removed first

12:35 queues usually have static size, but i guess its dynamic in clojure, right?

12:35 justin_smith: yeah

12:35 sometimes that is not what you want

12:35 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 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 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 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 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 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 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 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 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 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 (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 cbryan: Why not Scala instead?

13:21 I hear it's much faster than Clojure, if you're going for speed.

13:21 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 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 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 or that :p

13:32 the_danko: cbryan: execute in clojure jdbc

13:32 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 the rest should work

13:35 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 :classname :subprotocol :host :database :user :password

13:38 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 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 (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 maybe :subname i mean

13:44 keep googling

13:44 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 "" :database "favoritedogs" :user "user1" :password "xxxx"}

13:47 the_danko: cfleming: automatic line breaks would really be awesome!

13:47 justin_smith: thanks, trying it out now!

13:50 justin_smith: (def db

13:50 {:classname "org.postgresql.Driver"

13:50 :subprotocol "postgresql"

13:50 :user "user"

13:50 :password "pass"

13:50 :subname "//localhost:5432/webdev"

13:50 :unsafe true}) worked!

13:50 justin_smith: thanks a lot!

13:50 justin_smith: np

13:50 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 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 * EvanR hits == in vim to no avail

13:53 the_danko: justin_smith: with hope, cfleming will be rocking this shit soon in cursive!

13:54 the more times you say something, the truer it becomes

13:54 Bronsa: align-cljlet can indent map literals that way

13:54 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 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 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 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 (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 But, not relevant for #clojure I guess.

14:26 Thanks guys ^ Ill check those links.

14:27 mmeix: Is there a guide line concerning the order of a function's arguments?

14:27 for example:

14:27 (defn myfn [x coll] (remove #{x} coll))

14:27 or

14:27 (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 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 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 arrdem: we did not do pre-commit checks though. also i have never heard of lint until now.

14:33 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 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 arrdem ill check out

14:36 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 the_danko: astyle for Java/C++/C

14:40 bbloom: did you take the code format patches?

14:40 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 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 so, take that for what it's worth

14:50 bbloom: arrdem: yeah, i merged it and tweaked it a bit

14:51 arrdem: however, i should be clear that gofmt style code convention enforcement is a non-goal

14:51 i'm almost exclusively interested in debugging macros

14:51 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 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 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 "(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 (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 "static")) wrap-server )))

15:15 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

15:15 justin_smith: err

15:15 ,(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 is equivalent to (macroexpand `(-> a f1 (f2)))

15:19 => (-dev-main/f2 (-dev-main/f1 -dev-main/a))

15:19 (macroexpand `(-> a f1 (f2)))

15:19 => (-dev-main/f2 (-dev-main/f1 -dev-main/a))

15:19 (macroexpand `(-> a f1 ((f2))))

15:19 => ((-dev-main/f2) (-dev-main/f1 -dev-main/a))

15:20 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 Then see hiredman's message above for why #() interacts weirdly with this.

15:24 Finally, see if you can understand why my example above works the way it does: (-> a #((((((a)))))))

15:24 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 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 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 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 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 ,(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 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 TimMc: if you're bored. otherwise i'll figure it out. thanks again.

15:32 TimMc: First see what the reader does.

15:32 ,'(-> 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 ,((-> 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 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 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 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 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 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 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 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 *beaglebone

16:42 postpunkjustin: Yeah, Node is way better than the JVM for serving something like that on "cute" hardware

16:42 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 I kind of like Hy

16:44 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 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 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 looking into it

17:12 toxmeister: weird, just tried once more the same... and it worked this time!!

17:13 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 bit like `curl -v`

17:19 technomancy: toxmeister: you can try setting LEIN_DEBUG=y

17:19 or maybe just DEBUG=y

17:20 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 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 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 cider-jack-in starts a process, cider just finds one to connect to

17:29 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 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 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 *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 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 jcsims: thank you

17:41 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 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 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 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 )

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 badyl: https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L243 is kinda close

17:49 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 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 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 ,(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 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:08 * arrdem waves to Ft. Meade

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 what

18:36 Oh

18:36 right

18:37 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 (unless max-key just calls the key once)

18:38 on two

18:38 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 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 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 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 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 (defn max-by [f a b] (if (pos? (f a b)) a b))

18:47 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 It's not like comparing a number to a collection suddenly made sense.

18:54 technomancy: eeeeeh

18:54 I can see value in a universal comparator

18:55 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 ...but the channel returned from onto-chan never contained anything.

18:59 Instead I had to do something like:

18:59 (def c (chan))

18:59 (onto-chan c deck-of-cards)

18:59 ...and then I could pull my cards from channel c.

19:04 nathan7: andonilsson: (doto (chan) (onto-chan deck-of-cards))?

19:04 ,(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 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 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 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 and you probably want org.clojure/java.jdbc too

19:12 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 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 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 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 (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 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 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 haha

21:24 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 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 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 but does an extra walk, which is against the first criteria :)

21:26 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 ,(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 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 is there any benefit to writing the reduction as the final transduce step?

21:33 and is that even possible?

21:33 justin_smith: in that case, you should be able to compose the other ops with the transduce

Logging service provided by n01se.net