#clojure logs

2014-10-31

00:00TimMcI may have found it by searching for "clojure jobs", not really sure.
00:05cflemingIn my macroexpanded code, I'm occasionally seeing vars like G__1234 - does anyone know when the compiler inserts those?
00:06cflemingI've looked at all the uses of RT.nextID() and I can't figure it out.
00:06justin_smith,(gensym)
00:06clojurebotG__27
00:06cflemingAha, thanks.
00:06cflemingShows how many macros I write.
00:06justin_smithcfleming: they are in the reader for ` when you name something binding#
00:07justin_smith,`(let [foo# 1] foo#)
00:07clojurebot(clojure.core/let [foo__50__auto__ 1] foo__50__auto__)
00:07cflemingjustin_smith: Those are named <name>__1234__auto__, right?
00:07justin_smithahh, right
00:07justin_smithso the others are manual genzyms
00:07justin_smith*gensyms
00:07cflemingjustin_smith: The implicit parameters from a #() are p<num>__1234#
00:08justin_smith,'#(%)
00:08clojurebot(fn* [p1__75#] (p1__75#))
00:08justin_smithyeah
00:08cflemingOk, makes sense - those must be named in clojure.core - I'll take a look.
00:08justin_smith,(gensym "foo")
00:08clojurebotfoo102
00:09cflemingEw
00:09cflemingSo that one sucks
00:09justin_smithI think it is fairly rare...
00:09cflemingAll this is for detecting the changed region in the macroexpander I'm working on.
00:10justin_smithahh, right, of course
00:11cflemingSome of these are stable across expansions, but some of them are generated every time (G__1234 and pn__1234#)
00:11cflemingI guess I'll have to check whether two syms start with the same string but are suffixed with some different number for the named gensyms.
00:12justin_smithcfleming: what about a placeholder for the number part?
00:12justin_smithyeah
00:12justin_smithand not strictly a suffic, thanks to # being there sometimes of course
00:13cflemingYeah, I'm planning to shorten them all to things like name<n># for auto-gensyms, p<n># for the parameters and so on, I guess <name># for named gensyms and perhaps G<n># for the plain gensym case.
00:14cflemingFortunately there's only a couple of patterns.
00:16cflemingThanks!
00:40razum2umfrom clojure survey'14 I get to know, that people would like to see "feature experessions" in the language. the idea initially comes from cljx and reminds me on c-ifdef's. i didn't write any cljs yet, but i ask you: is it really needed? I thought, that business logic should be ideally platform independent, why it won't get solved by proper "interface" for functions which deal with host-related things?
00:44justin_smithrazum2um: in practice you can reduce the complexity of the codebase by allowing certain expressions to be swapped out based on the backend
00:44justin_smithrazum2um: the advantage over C macros is that they are syntax aware, so it's much harder to get the bizzarre results that a bad C macro could give you
00:45razum2umjustin_smith: is it really needed only as "syntactic sugar"?
00:45razum2umonly to reduce file count?
00:46justin_smithrazum2um: I don't know about calling it sugar. Each ns where you can use a feature expression means at least 2 files you don't need. Also, it's more straightforward to read and understand the code when key parts of it aren't split into separate files for backend rather than conceptual organization reasons
00:48justin_smithseparation of concerns can simplify things, but when you are splitting things based on impl but sharing others, that can easily be fragmentation of the design rather than simplification.
00:49mindbender1is there a function I can use to output the bit representation of a number in 1s and 0s?
00:49justin_smithmindbender1: I think there is something in cl-format that can do that
00:49razum2umjustin_smith: hm, this reminds me on nodejs and meteorjs. people are trying to merge codebases and finally they end up with "is_this_a_server_or_client" functions. I still think, that only some business logic should be shared and it could and must be written platform independent, or am I an idealist?
00:50justin_smith,(require '[clojure.pprint :as pprint])
00:50clojurebotnil
00:50justin_smith,(pprint/cl-format "~1r" 88)
00:50clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
00:51justin_smith,(pprint/cl-format nil "~1r" 88)
00:51clojureboteval service is offline
00:52justin_smithrazum2um: tangent - when using the term "business logic" - what is the distinction, what part of the code is not business logic?
00:54mindbender1justin_smith: I'm trying to read up the docs
00:54justin_smithrazum2um: what happens is that you can have, for example, a common data structure between clj and cljs, and want to be able to do the same operations, but you have a small number of operations that need to be implemented differently. being able to describe those differences (if they are very small in number) inline rather than through two more namespaces, can make everything much simpler.
00:54razum2umhm, say "valid user should have name and email" - (defn valid_user? [u] (every? some? ((juxt :email :name) u))))
00:55mindbender1justin_smith: see http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/clm/node199.html
00:55justin_smith,(pprint/cl-format nil "~b" 88) ; mindbender1
00:55clojurebot"1011000"
00:55mindbender1ok
00:55justin_smithmindbender1: I don't mean the format function in common lisp - the clojure function called cl-format
00:56razum2umjustin_smith: perhaps in practice you're right and i need to write more cljs %)
00:56mindbender1justin_smith: yeah. The docstring points there.
00:56justin_smithmindbender1: what you link to is different - it's not about the ascii base 2 rep, it's about outputting raw bytes
00:56mindbender1okay
00:56mindbender1thanks for clarifying
00:57justin_smithrazum2um: I think it's something about which reasonable people can disagree, you asked about the rationale so I do my best to present it
00:57razum2umjustin_smith: but actually appearence of cljx points on the fact, that there is already a huge amount of cljs code, what are companies who do have them?
00:58justin_smithrazum2um: my previous employer, who I now do some contracting for, has some cljs code
00:59justin_smithrazum2um: for example here http://www.onenorthpdx.com/
01:10mindbender1justin_smith: can't cl-format output hex as well?
01:10mindbender1can
01:10justin_smith,(pprint/cl-format nil "~x" 99999)
01:10clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: pprint, compiling:(NO_SOURCE_PATH:0:0)>
01:11justin_smith,(clojure.pprint/cl-format nil "~x" 99999)
01:11clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint>
01:11justin_smith,(require '[clojure.pprint :as pprint])
01:11clojurebotnil
01:11justin_smith,(pprint/cl-format nil "~x" 99999)
01:11clojurebot"1869f"
01:12justin_smith,(pprint/cl-format nil "~x" 16rdeadbeef)
01:12clojurebot"deadbeef"
01:12justin_smith,16rdeadbeef
01:12clojurebot3735928559
01:13mindbender1okay. thanks
01:43mindbender1,(pprint/cl-format nil "~2,8,'0r" x)
01:43clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: pprint, compiling:(NO_SOURCE_PATH:0:0)>
01:44mindbender1,(require '[clojure.pprint :as pprint])
01:44clojurebotnil
01:44justin_smithx is still unbound
01:44mindbender1,(pprint/cl-format nil "~2,8,'0r" 5)
01:44clojurebot"00000101"
01:44mindbender1just wanted to say thanks
01:44justin_smithnp
01:54marshall_hey clojure
01:54justin_smithhello
01:55marshall_i'm almost 100% completely new to clojure and java. I'm trying to run a simple web service that uses a cool clojure library and i'm getting this error: https://gist.github.com/anonymous/3519fa9c8b5714d209fd
01:55marshall_is it something simple that i just don't understand? syntax maybe?
01:57TEttingermarshall_: just off the top of my head, you have a vector that contains just :post, could it be expecting and converting to a hash-map (which needs an even number of entries, 1 key to 1 value)
01:57TEttinger:access-control-allow-methods [:post]
01:57TEttingerthat part
01:57TEttingeroh!
01:58marshall_TEttinger: yeah, that's the part that clojure was complaining about
01:59marshall_i just pasted from here: https://github.com/r0man/ring-cors
01:59TEttingerit apparently converts all the args to wrap-cors to a hash-map, you should double-check the usage of that code (it seems like it's a macro)
01:59marshall_i only want to allow the POST method, so I removed the other methods from that part
02:01TEttingeroh, gotcha
02:01TEttingerit has to do with ->
02:01justin_smithmarshall_: take out app-routes
02:01justin_smithfrom the wrap-cors call
02:01justin_smithit throws off the hash-map construction
02:02TEttinger-> is called a threading macro, it takes an initial value and threads it (not concurrency threads, like threading a needle) by inserting it as the first arg to the next function given. then the result of that is inserted as the first arg to the function after that, and so on
02:03TEttinger,(-> 100 (+ 10 10) (/ 12))
02:03clojurebot10
02:03TEttingerso that takes 100, then makes the next piece into (+ 100 10 10) getting 120, then makes the next piece into (/ 120 12) getting 10
02:04fairuz,(->> 100 (+ 10 10) (/ 12))
02:04clojurebot1/10
02:04TEttingerand ->> does the same thing with the thread inserting in the last argument position
02:05marshall_ok
02:06TEttingerso what justin_smith is saying is, app-routes is already supplied as the first arg by -> , so when you have it again it treats it as part of the hash-map it's constructing and you and up with an odd number of elements it tries to pair into keys and values
02:06marshall_ahh I see
02:06marshall_that's a handy feature
02:06TEttingerquite!
02:07marshall_i think they call that a currying function in javascript
02:07marshall_or i guess in most other languages
02:09TEttingerkinda, -> actually works a bit differently. we have currying in the form of a function that returns functions, called partial
02:09TEttinger(doc partial)
02:09clojurebot"([f] [f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & ...]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."
02:10TEttinger,(map (partial + 10) [1 2 3])
02:10clojurebot(11 12 13)
02:10marshall_hmm
02:10marshall_awesome
02:10TEttingermap I think is called map in javascript?
02:11TEttingermap, apply, filter are some of the most commonly used functions in clojure
02:11marshall_map in javascript is when you apply a function to the elements of an array and replace each element with the result of that function
02:11TEttingeryep
02:11TEttingerhere, it returns a new collection, with state possibly shared
02:11TEttingerthat's just an optimization clojure does
02:12marshall_[1,2,3].map(function(num){ return num +1 }) // >> [2,3,4]
02:12marshall_i removed the app-routes parameter
02:12marshall_but now I get a 404 for my one route
02:13marshall_could it be the order of my middleware?
02:13TEttingerbut you don't have to think about defining some collection, running a map on it several times in an uncertain order, and then the collection was changed in some weird order the next time you use it -- that doesn't happen in clojure
02:13TEttingeruh, I am not familiar with ring
02:14marshall_hmm
02:14TEttingerit looks like wrap-cors returns something that expects one arg?
02:14TEttingerhttps://github.com/r0man/ring-cors/blob/master/src/ring/middleware/cors.clj#L67
02:17marshall_what's clojure really good for? what do you use it for?
02:17marshall_i'm coming from python and node.js
02:17marshall_javascript
02:19justin_smithmarshall_: it makes concurrency sane, and once you "get it", it helps facilitate a programming style that eliminates incidental complexity
02:19shane1It's jvm based, so I use it for doing functional programming with interop with java
02:19justin_smithmarshall_: part of that is the idioms / supplied libs, but things like immutibility really help with that
02:20justin_smithmarshall_: I wouldn't use it if I need low ram usage or fast startup, but for a process that can use as much ram as it might need, and stays running a long time, it is awesome
02:23marshall_justin_smith: ahh i see
02:23marshall_shane1, justin_smith: thanks
02:26justin_smithmarshall_: for a proper function written to act on immutible data, all you need to understand in order to understand what that function does is what it explicitly acceses in the body. This is a major game changer that effects everything from code reading, to unit testing, to refactoring.
02:27justin_smithmarshall_: also code reuse, it is easier to write modular functions that can be reused if you know they contain no implicit dependencies or state
02:29marshall_interesting
02:30marshall_anybody have experience with ring? I'm trying to use CORS middleware
02:30justin_smithyes, I use ring all the time
02:33marshall_justin_smith: what am I doing wrong here? https://gist.github.com/jeffmarshall/b85a3f5fa6fe0e307112
02:33marshall_i only have one route and it gives me a 404 now that I've included the cors middleware
02:34justin_smithmarshall_: I don't know that particular middleware, but it seems that it only allows post, and only allows requests from that specific host regex?
02:35marshall_hmm
02:35marshall_ok
02:37justin_smithmarshall_: I am not sure because I don't know that middleware though
02:38marshall_justin_smith: have you ever done anything in ring with CORS?
02:41justin_smithmarshall_: no I have not
02:47marshall_justin_smith: dang
02:48justin_smithmarshall_: but the quantity of things to know about ring that you don't know is probably smaller than the quantity of things about cors that I don't know, and if we discuss it we can probably sort out what is going on
02:48justin_smithor is it visa versa? no matter
02:56justin_smithmarshall_: I am working on a deploy to staging so my client can verify some work, (deploying a ring site even :)) but I can definitely help you sort this out afterward if you like
04:26sveri80Hi, I am trying emacs again and started a repl in my project and connected to it with cider, now, then I try to load a buffer with cider-load-current-buffer, nothing happens in the connected repl, what is wrong there?
05:41vyvuphi, I am trying to use ring.server.standalone from the REPL iso. using lein ring server-headless. For some reason their auto-reload behavior is slightly different, does anyone know why?
05:42vyvupe.g. changing strings inside a defroutes macro do not update using standalone, but do in lein
05:43vyvuplooking at the sources I couldn't find a real difference between how they handle things
05:55clgvvyvup: I haven't used these modes (I guess). but you'll only get updates when the server runs in the same repl you use to update your code
05:55clgverrr. function implementation instead of code.
05:56clgvvyvup: for routes you usually need to pass the variable (instead of the value) of the routes constant or routes function to the call that starts the server
06:06vyvupclgv: see ix.io/eZp for handler code
06:06vyvupthe repl commands that i use are there inside comments
06:07vyvupclgv: I am sorry but don't quite understand what you mean
06:08clgvvyvup: change your startup to (def server (ring.server.standalone/serve #'clojure-testapp.core.handler/app))
06:08vyvupok, will try
06:08clgvvyvup: this way you have an indirection through the variable and get the latest changes
06:09clgvvyvup: you know about refheap.com ?
06:09vyvupnope, but now i do :)
06:12vyvuphmm, still does not work: what does the #' combination do?
06:12TEttinger##(clojure.string/join ", " (range 500))
06:12lazybot⇒ "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, ... https://www.refheap.com/92509
06:13TEttingerneat feature of lazybot is the automatic link to refheap for long printed returns
06:13vyvupclgv: the namespace is reloaded: the do-bye function to return another string it updates correctly
06:13TEttingervyvup: it's the var-quote , it's documented at the clojure site but there's another guide out there
06:14TEttingerhttp://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/
06:14clgvTEttinger: haha great
06:14TEttingerit's a great guide
06:14vyvupTEttinger: ah, nice :)
06:15clgvvyvup: yeah, it should reload your routes assigned to the variable "app"
06:15vyvupyes, but it also did that without the #'
06:15clgvvyvup: do you reload the namespace where "app" is defined or just reevaluate the definition of "app"?
06:16clgvvyvup: didn't you say your routes were not updated?
06:16vyvupI depend on the reload behavior of (serve)
06:17clgvif `serve` is not a macro you should pass the variable `app`
06:17vyvupwell, they are reloaded partly: everything outside the macro definition is reloaded, but e.g. changing the string returned by "/hello" does not propagate
06:18clgvvyvup: yes, that is because you do not use the var ;)
06:18vyvuphmm, but when I do use the var it also does not work
06:18clgvvyvup: you have to pass the var and you need to reevaluate the whole namespace or: first `app-routes` and then `app`
06:20vyvupah, it seems I screwed up something else :)
06:23vyvupclgv: yay, works \o/ thanks! I will read up on the macro stuff
06:28TEttinger(inc clgv)
06:28lazybot⇒ 32
06:47clgvthanks
07:01luxbockis it just me or has the syntax hilighting for Clojure code at Github got significantly worse?
07:04jonathanjis there a solution to the crappy let/with-open nesting you get when you need things to be defined in a certain order?
07:05jonathanj(let [path (temp-file)] (with-open [output (output-thing path)] (let [obj (Obj. output)] ...
07:05jonathanji need to return path, so i can't just inline it
07:09SagiCZ1i dont understand how could i not care about types of my sequences when conj appends to beginning or end depending on wheter its a vector or not.. thats absolute madness
07:31raspasovSagiCZ1: do you have specific example in mind?
07:33borkdudeSagiCZ1 of course you care, but you usually know what you're dealing with
07:33SagiCZ1when i call (last (conj coll)) for example..
07:33SagiCZ1borkdude: no i dont.. some clojure functions return random weird types how am i supposed to know what they return
07:34borkdudeSagiCZ1 they don't return random types. most sequence functions return lazy sequences
07:34SagiCZ1for example take-last returns PersistentVector, or PersistentVector$ChunkedSeq, or clojure.lang.Cons depending on the constellation of stars i guess
07:34clgvluxbock: it's just you. the colors and fonts change afaik
07:34borkdude,(doc take-last)
07:34clojurebot"([n coll]); Returns a seq of the last n items in coll. Depending on the type of coll may be no better than linear time. For vectors, see also subvec."
07:34borkdudeIt returns a seq.
07:35SagiCZ1,(type (take-last 2 [5 4 3 2 0]))
07:35clojurebotclojure.lang.PersistentVector$ChunkedSeq
07:35SagiCZ1looks like PersistentVector$ChunkedSeq to me
07:35borkdude(conj (take-last 2 [1 2 3]) 0)
07:35borkdude,(conj (take-last 2 [1 2 3]) 0)
07:35clojurebot(0 2 3)
07:35borkdudethat's perfectly predicable
07:35borkdudeSagiCZ1 yes, PersistentVector.....Seq <- seq
07:35clgvSagiCZ1: that is a Seq just an implementation detail which class provides the seq methods ;)
07:35SagiCZ1but why does it return java.lang.Cons sometimes?
07:36SagiCZ1i mean clojure.lang.Cons
07:36raspasovSagiCZ1: in most cases you don't care about either of those, if you have a bigger example or gist we might be able to suggest more constructively - usually there's a nice idiomatic way to do things
07:36borkdude,(type (list 0))
07:36clojurebotclojure.lang.PersistentList
07:36borkdude,(type (list))
07:36clojurebotclojure.lang.PersistentList$EmptyList
07:36clgv&(-> clojure.lang.Cons ancestors)
07:36lazybot⇒ #{clojure.lang.ASeq clojure.lang.Sequential clojure.lang.IObj java.util.Collection java.lang.Iterable clojure.lang.Seqable clojure.lang.Obj java.lang.Object java.util.List clojure.lang.IMeta java.io.Serializable clojure.lang.IHashEq clojure.lang.ISeq clojure.lang.IPersistentCollection}
07:36borkdudeSagiCZ1 I don't even remember what returns a Cons, and I work with clojure pretty much every day
07:36borkdudeSagiCZ1 not important
07:37clgvSagiCZ1: cons ia a seq as well as you can see above ;)
07:37SagiCZ1i am acessing only last n itemes from a vector.. if i use it as is, it works fine.. if i call (take-last (* 2 n) coll) on that vector before that, my program no longer works
07:37clgvborkdude: not-so-lazy lazy functions do that sometimes, because there impl starts with `cons` instead of `lazy-seq`
07:37raspasovas a rule of thumb in Clojure, you try to stick to vectors [1 2 3] or maps {:a 1 :b 2}; and you remember that map, filter, and reduce return a sequence
07:38borkdudeyes, and if you really want to keep it strict, use mapv, filterv or transducers
07:38clgvSagiCZ1: you mean two time take-last?
07:38clgvSagiCZ1: the problem is take-last returns a seq and does not preserve the type vector
07:39raspasovSagiCZ1: use subvec for vectors
07:39SagiCZ1clgv: isnt that what i am talking about?
07:39clgvSagiCZ1: you could also implement as special take-last via sub-vec
07:39borkdude,(vec (take-last 2 (range 10))
07:39clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
07:39raspasovhttps://clojuredocs.org/clojure.core/subvec
07:39borkdude,(vec (take-last 2 (range 10)))
07:39clgvSagiCZ1: no. because take-last always returns seq and you talk about alternating return types
07:39clojurebot[8 9]
07:39raspasovuse subvec, it's guaranteed O(1)
07:40clgvsplitting hairs: take-last is O(1) as well - just not the realization part ;)
07:40borkdudeuse sequence functions and don't care about concrete types, until you expose them. premature optimization if you do I think
07:40SagiCZ1clgv: but sometimes it returns PersistentVector$chunkedSeq and sometimes clojure.lang.Cons .. andi guess my program depends on it for some reason
07:40clgvSagiCZ1: both are seqs just different implementations
07:40Bronsa SagiCZ1: those two types behave the same way unless you are explicitely testing for instanceness
07:41clgvno it does not. it might depend on the fact that you assume a vector where you get a sequence
07:41SagiCZ1ok thanks.. there is some super weird bug then.. i guess im just going crazy
07:41BronsaSagiCZ1: when clojure talks about returning a seq, it means it will return an object whose type implements ISeq
07:41Bronsano concrete type is guaranteed
07:41raspasovSagiCZ1: again, feel free to post a larger gist, we might be able to suggest something better
07:41SagiCZ1i use the return type in these functions:
07:41SagiCZ1apply, count, nth, last
07:41SagiCZ1shouldnt all these work fine for both types?
07:43raspasovit gets subtle, for example nth on a sequence is O(N) https://clojuredocs.org/clojure.core/nth
07:43raspasovfor some details I recommend https://www.youtube.com/watch?v=iQwQXVM6oiY
07:43BronsaSagiCZ1: yes, they should. can you paste a gist with the code that you're talking about as the other suggested?
07:44SagiCZ1Bronsa: its spread through some files, i will look into it more and then construct some minimal example
07:45BronsaSagiCZ1: early on you said that take-last returns a PersistentVector, that's never the case by the way.
07:49SagiCZ1,(type (take-last 3 [2 0])
07:49clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
07:49SagiCZ1,(type (take-last 3 [2 0]))
07:49clojurebotclojure.lang.PersistentVector$ChunkedSeq
07:49SagiCZ1Bronsa: ok i guess i get confused.. im trying to solve this bug for about 5 hours now..
07:56clgvSagiCZ1: build small composable functions, test these individually
09:14si14urgh. is there any reason why Lein can skip local .m2 repo? I have my Datomic installed there, and yet lein deps fails
09:22hyPiRionsi14: different Datomic versions – I don't think lein would check if the version is already there
09:22hyPiRionsi14: you don't have to use lein deps anymore though, fyi
09:24si14hyPiRion: yeah, lein repl also fails :) versions are same
09:25si14ah, I see: ls ~/.m2/repository/com/datomic/datomic-pro/0.9.4956 > datomic-pro-0.9.4956.jar.sha1 datomic-pro-0.9.4956.pom.sha1 _maven.repositories _remote.repositories
09:25hyPiRionsi14: yes
09:26si14hyPiRion: looks like a maven/Datomic bug then, because mvn build finishes without errors
09:29hyPiRionsi14: Perhaps, but it may be that they store it somewhere else. Why the directory contains the sha but not the jar, I don't know.
09:31si14finally solved it. it seems that if you use remote repository and then switch to local one, mvn install will not actully install datomic locally
09:32si14you need to remove ~/.m2/repository/com/datomic manually first
09:37TimMchyPiRion: I superstitiously run `lein do clean, deps, compile, javac, midje, junit, uberjar` when I build.
09:39hyPiRionTimMc: Let's :prep-task ourself?
09:40hyPiRionsounds reasonable.
09:41fairuzanyone use Titanium here?
09:42csd_anyone around that hosts on heroku?
09:43daniel__my laptop has some titanium in it
09:43fairuzdaniel_ :)
09:46clgv~anybody
09:46clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
09:47csd_:)
09:47csd_my sql server connection seems to be timing out on heroku. i'm wondering what the best way to fix it is.
09:47csd_happens after like 30 or so minutes of inactivity
09:48TimMcI don't think Heroku supports persistent connections like that.
09:48csd_do you know how to have korma reconnect to the db in that case? i was looking through the source and it wasnt clear to me how to do it
09:49jonathanjwhy is the result of (if-let [{x :x} {:not-x 5}] x "nope") different to (if-let [x (:x {not-x 5})] x "nope")?
09:49jonathanjerr, :not-x in the second example
09:49TimMccsd_: Wait, Korma relies on a persistent connection? What do you mean by timing out, exactly?
09:49jonathanj,(if-let [{x :x} {:not-x 5}] x "nope")
09:50clojurebotnil
09:50jonathanj,(if-let [x (:x {:not-x 5})] x "nope")
09:50clojurebot"nope"
09:50csd_TimMc: I think so? Because that's what I'm relying on and and it doesn't seem to be reconnecting right away.
09:50csd_What happens is that I have to make two http requests. The first fails and returns a blank page, which seems to reconnect to the sql server. And then the second request works.
09:51fairuzI can connect OK when I run Titan DB on the same machine as my app, but when I try to connect to a remote Titan DB, it fails with IllegalArgumentException. I'm using Titanium library to connect to this DB. Any advise on this error?
09:55csd_I suppose I could have my app do something like SELECT 1 every 5 minutes. I think that might work.
09:58xeqijonathanj: the if portion is checking against {x :x}. This will always be truthy. Destructuring doesn't effect the if portion
09:58jonathanjxeqi: ah, okay
09:59jonathanjxeqi: thanks
10:00xeqiwell, checking against {:not-x 5}, which is truthy
10:06jonathanjis putting complex if-let forms in let-like bindings usually a good idea or not?
10:06jonathanj(i'm guessing if i'm asking this, it's probably not)
10:10csd_ i wouldn't want to sacrifice clarity for brevity personally
10:12clgvjonathanj: depends. you'd have to show examples to judge
10:13jonathanjis there a preferred paste-bin for this channel?
10:14clgvrefheap.com
10:15clgvor something else with clojure syntax highlighting and without tons of ads ;)
10:15clgvgists on github work as well
10:15xemdetiaWas refheap ever compromised or something?
10:16clgvwhy?
10:16clojurebotclgv: because you can't handle the truth!
10:16clgvclojurebot: right
10:16clojurebotGabh mo leithscéal?
10:16jonathanjhttps://gist.github.com/jonathanj/30530c685d44cf45fbb7
10:16xemdetiaI'm just getting a warning when I tried to look there
10:16xemdetiaoh well, probably just an oversight
10:16clgvhumm I dont get any
10:17borkduderefheap rules
10:17clgvxemdetia: firefox accepts the ssl certificate as valid
10:17borkdudebecause Raynes built it
10:17clgvxemdetia: is someone eavesdropping on you?
10:18clgvxemdetia: looks fine to me. could be improved with some->
10:18clgvjonathanj: ^^
10:18xemdetiaclgv, yes- employer is and it just gets flagged as possibly malicious
10:18xemdetiathat's why I was curious
10:18jonathanjclgv: some->?
10:19clgvjonathanj: ah wait, cond->
10:19borkdudeconj->
10:20jonathanjhow would you rewrite it?
10:20clgvjonathanj: page (:signature options), input-path (cond-> input-path page (vector (fill-fields page)))
10:21clgvjonathanj: you could also pull `page` in a local scope within a `let` surrounding the `cond->`
10:22clgvjonathanj: 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:23clgv*forget
10:23jonathanjcan i shadow existing names?
10:23clgvjonathanj: yeah
10:24jonathanjis the name only bound after evaluating the RHS of the let expression?
10:25clgvjonathanj: you could say so. the result of the RHS expression is referred to via the name in the remaining scope
10:26jonathanjclgv: your cond-> example, what comes before the "page (:signature" bit?
10:26jonathanjoh, i see, it's in the containing let
10:27clgvyeah exactly
10:27clgvbut 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:29jonathanjyeah, that code i pasted is already in an existing let (as i mentioned), the let alignment is getting quite... unmanageable
10:29jonathanjthanks, that helped
10:30clgvjonathanj: maybe you could use smaller functions then
10:32jonathanjclgv: yes, that is almost certainly likely
10:32jonathanji'm enhancing what was my first ever clojure application
10:34jonathanjif 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:34jonathanji guess it's more writing from the caller's perspective but it's certainly a lot more readable
10:37clgvjonathanj: maybe you should organize the data in a map in the first place?
10:41jonathanjclgv: hrm, well it's mostly wrestling command-line options to call some Java code
10:41jonathanjbut i'll take a look at refactoring once i'm done implementing the enhancement
10:41jonathanjso i'm getting this warning: Reflection warning, clj_neon/core.clj:262:11 - call to setField can't be resolved.
10:42clgvjonathanj: is clj-neon your implementation=
10:42jonathanjyes
10:42jonathanji'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:43jonathanjhttps://gist.github.com/jonathanj/f5a419717c782a827b0d
10:43clgvok 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:43jonathanjhttp://api.itextpdf.com/itext/com/itextpdf/text/pdf/AcroFields.html#setField%28java.lang.String,%20java.lang.String%29
10:43jonathanjoh
10:44clgvjonathanj: maybe you have a different version?
10:44jonathanji'm calling the method on the wrong object
10:45jonathanjokay, i'll stop spamming the channel with my trivialities, thanks for your help clgv
10:45clgvgood luck
11:14sdegutisAre transducers as wonderful as the memes make it out to be?
11:14sdegutiszoom__: uhh
11:14sdegutiszoom__: why did you PM me some spam link just now?
11:14hyPiRionsdegutis: bot
11:15borkdudesdegutis always be decomplecting is the first meme of all
11:16csd_what's the easiest way to extend a package that i'm using--a relatively small edit
11:17csd_i dont really want to have to fork it
11:18bbloomcsd_: 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:19bbloombut really, forking isn't so bad when you've got an application to ship
11:19csd_well i don
11:19csd_dont
11:19csd_this is more just for fun
11:20csd_i want to override korma to send a sql command over its jdbc connection
11:20winkcsd_: why does exec-raw not work?
11:22csd_oh that should actually do it. i didnt see that
11:22csd_thank you
11:23winkthe docs are a bit.. yeah :)
11:23csd_haha
11:23winkI fell into that trap as well. "such a cool library, why wont it let me exec sql?"
11:23csd_"such a cool library, why does it have zero foreign key support"
11:24winkso you seem to use postgres? .oO( No one uses FKs with mysql )
11:24csd_i use mysql
11:24csd_i guess i just do things the hard way
11:26EvanRi used foreign key constraints with mysql, at some point
11:26winknah, I just find it atypical
11:26EvanRit was a real bitch
11:26winkmost people don't
11:26winkmaybe historical reasons as it was hard with 3.x or 4.x
11:26csd_ive never used postgres. my brother keeps telling me to try it
11:26EvanRuse postgres if its got to be sql
11:27csd_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:27EvanRreally knowing postgres is really good
11:28EvanRand sql sucks
11:28EvanRso do key value stores
11:33csd_wink: are you pretty familiar with korma?
11:33winkcsd_: nope, used it in 2 small projects
11:42jez0990hey #clojure, why is the ordering of transduce arguments opposite to the ordering of comp - is it is just a stylistic decision?
11:43justin_s`jez0990: each arg acts not on the output of the previous, but on the previous funcion
11:43justin_s`by wrapping it
11:44nkozajez0990: there is a recent thread on the clojure mailing list about that exact issue
11:44justin_s`so it inverts the logical order
11:44borkdudejez0990 ah way you can remember: transducers correspond to ->>
11:48jez0990justin_smith: nkoza borkdude: thank you :)
11:56sdegutisborkdude: Good to know, thanks.
11:59EvanRwhat is the function to convert a string of digits into a number
11:59justin_smithEvanR: one for each of the primitive numeric types
11:59borkdudeor just edn/read-string
11:59justin_smith,(Long/parseLong "1")
11:59clojurebot1
12:00EvanRparseLong, done
12:00EvanR,(Long/parseLong "123e")
12:00clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "123e">
12:00EvanR,(Long/parseLong "")
12:00clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "">
12:00borkdude,(read-string "123e")
12:00clojurebot#<NumberFormatException java.lang.NumberFormatException: Invalid number: 123e>
12:00EvanR,(Long/parseLong "-1")
12:00clojurebot-1
12:00borkdudeis that a thing, 12e3?
12:00EvanRi was testing what happens if the prefix is a valid number
12:01justin_smith12e3 is scientific notation, dunno about 123e
12:01EvanR,(Long/parseLong "12e3")
12:01clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "12e3">
12:01borkdude,(read-string "12e3")
12:01clojurebot12000.0
12:01borkdudeyeah ok
12:01justin_smith,(Double/parseDouble "12e3")
12:01clojurebot12000.0
12:01EvanRi picked a bad letter for that test
12:01justin_smith:)
12:01justin_smith,(Double/parseDouble "123e")
12:01clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "123e">
12:01justin_smithstill fails as a suffix
12:02clgv,(Double/parseDouble "123abc")
12:02clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "123abc">
12:02clgv;)
12:02EvanR,(Long/parseLong "123z")
12:02clojurebot#<NumberFormatException java.lang.NumberFormatException: For input string: "123z">
12:04justin_smithEvanR: 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:04sdegutisbbloom: 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:05bbloomsdegutis: assumes you care to upgrade ever
12:05sdegutisbbloom: 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:06sdegutisbbloom: Right. Depends on things like whether the lib has inherent security needs, etc.
12:09EvanR,(edn/read "true")
12:09clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: edn, compiling:(NO_SOURCE_PATH:0:0)>
12:09EvanR,(edn/read "123")
12:09clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: edn, compiling:(NO_SOURCE_PATH:0:0)>
12:10noonian,(clojure.edn/read-string "true")
12:10clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.edn>
12:10sdegutisEvanR: you gotta require it
12:10EvanRrequired to require
12:10noonian,(do (require '[clojure.edn :as edn]) (edn/read-string "true"))
12:10clojurebottrue
12:10justin_smith,(require '[clojure.edn :as edn])
12:10clojurebotnil
12:10justin_smithheh, beat me to it
12:10EvanR,(edn/read "123")
12:10clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.io.PushbackReader>
12:10EvanR,(edn/read-string "123")
12:10clojurebot123
12:10sdegutis,(edn/read-string "(map map)")
12:10clojurebot(map map)
12:11andyfI worked on a project where I was used to require, but was required to use. refer madness
12:11noonian,(edn/read-string "(map map in your hat)")
12:11clojurebot(map map in your hat)
12:11EvanR,(edn/read-string "'(1 2 3)")
12:11clojurebot'
12:12justin_smithEvanR: with read, it would also move the stream forward, so the next read would get the next token
12:12justin_smithbut you need a pushbackreader for read
12:13clgv,(read-string "'(1 2 3)")
12:13clojurebot(quote (1 2 3))
12:15justin_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:15clojurebotjustin_smith: I don't understand.
12:16justin_smith:P
12:18justin_smith,(let [in (java.io.PushbackReader. (clojure.java.io/reader (.getBytes "1 2 :a [1 2 3] \"hello, world\"")))] (take-while identity (repeatedly #(and (.ready in) (edn/read in)))))
12:18clojurebot(1 2 :a [1 2 3] "hello, world")
12:18justin_smiththere we go!
12:19EvanRpush back reader
12:19justin_smithyeah, 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:19EvanRjuke box hero
12:20justin_smith?
12:20EvanRimmediately what came to mind based only on the arity of syllables
12:20clgvjust define a custom lazy-seq it'll end on nil ;)
12:20EvanRyeah "ungetc"
12:21justin_smithclgv: oh yeah, I could have done it with an fn making a lazy seq with self calls, yeah
12:21EvanRself calling a fn, does this bust the stuck potentially?
12:21EvanRstack
12:22clgvnot in a lazy-seq ;)
12:22justin_smithEvanR: no, because lazy-seq transforms it into a thunk
12:22EvanRfun times
12:23noonianrecursion is the funnest
12:24justin_smithnoonian: also, the funnest is recursion
12:25cbryanjustin_smith: but don't forget that recursion is the funnest
12:25justin_smithI propose we rename iterate to turtles
12:25noonianGNU has the best recursive acronyms
12:26clgvjustin_smith: no then it would be mutual recursion ;)
12:27justin_smithclgv: that's recursion
12:27clgvjustin_smith: recursion is almost recursion ;)
12:28clgvjustin_smith: "to understand recursion you have to know someone who understands recursion" ;)
12:29silasdavisis there a way to get leiningen to add some arbitrary files to your jar?
12:29clgvsilasdavis: put them under the resource path
12:29justin_smithclgv: 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:29EvanRto understand recursion you need a base case to avoid an infinite regression
12:29technomancysilasdavis: easiest way is to plop them in resources/ put you can use :filespecs too
12:30clgvjustin_smith: haha :D
12:30clgvEvanR: no, base cases take away all the fun! :P
12:30justin_smithclgv: his claim was that all human knowledge was recursive
12:31noonianinfinite recursion works, its just usually not what you want unless you are making an interpreter or something
12:31silasdavistechnomancy: thanks I thought of using resources. I didn't know about filespecs, these are vendored dependency executable binaries
12:31justin_smithclgv: though he preferred the term "circular"
12:31clgvjustin_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:32technomancysilasdavis: resources/ is fine for that; there's no requirement that they be text
12:32justin_smithclgv: yeah, I have played that one too :)
12:32SagiCZ1,(-> clojure.lang.PersistentQueue/EMPTY (conj 5) (conj 42))
12:32clojurebot#<PersistentQueue clojure.lang.PersistentQueue@486>
12:32SagiCZ1,(seq -> clojure.lang.PersistentQueue/EMPTY (conj 5) (conj 42)))
12:32clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->, compiling:(NO_SOURCE_PATH:0:0)>
12:32justin_smith,(seq (conj clojure.lang.PersistentQueue 5 42))
12:32clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IPersistentCollection>
12:33SagiCZ1,(seq (-> clojure.lang.PersistentQueue/EMPTY (conj 5) (conj 42)))
12:33clojurebot(5 42)
12:33SagiCZ1isnt it backwards?
12:33justin_smith,(seq (conj clojure.lang.PersistentQueue/EMPTY 5 42))
12:33clojurebot(5 42)
12:33clgvjustin_smith: damn! tapped in "Greek" -> "Modern Greek" -> "Greek"
12:33justin_smithSagiCZ1: that's what a queue does, it adds to the end, removes from the front
12:33SagiCZ1justin_smith: ok i though it was the other way around, np
12:34justin_smith,(seq (pop (conj clojure.lang.PersistentQueue/EMPTY 5 42)))
12:34clojurebot(42)
12:34justin_smithsee, the 5 is gone
12:34justin_smithFIFO
12:34SagiCZ1yeah.. FIFO
12:34SagiCZ15 came first so it gets removed first
12:35SagiCZ1queues usually have static size, but i guess its dynamic in clojure, right?
12:35justin_smithyeah
12:35justin_smithsometimes that is not what you want
12:35justin_smithjava of course has bounded ones
12:36SagiCZ1and if i wanted to remove more than one element by popping, can i just call pop repeatedly?
12:37clgvO_o
12:37justin_smithSagiCZ1: remember that this is a persistent data structure
12:38SagiCZ1i understand it will not mutate
12:38justin_smithSagiCZ1: 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:38justin_smithSagiCZ1: maybe there is a more convenient method for this...
12:39SagiCZ1i am still trying to come up with the best data structure for my problem.. cant be that hard
12:39SagiCZ1vectors kinda work
12:40hyPiRionSagiCZ1: you can use core.async as well, if that fits
12:40justin_smithSagiCZ1: 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:41SagiCZ1justin_smith: yes
12:41justin_smithSagiCZ1: a queue is actually designed for this FIFO behavior that is inherent to your algorithm
12:41justin_smithalso, as hyPiRion mentions, core.async is, among other things, an interesting DSL over queues
12:42SagiCZ1i 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:43SagiCZ1does that make any sense?
12:43justin_smithI think so, yeah
12:43clgvSagiCZ1: you can just do that, by writing a custom `queue-conj`
12:44SagiCZ1clgv: 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:44justin_smithSagiCZ1: why not remove items from the queue if they have been processed?
12:45SagiCZ1justin_smith: because i always need last n items, not just the very last item
12:45SagiCZ1n is constant
12:45clgvSagiCZ1: sliding window? moving averages?
12:45justin_smithSagiCZ1: OK, then hold onto exactly n items :)
12:45SagiCZ1clgv: exactly
12:47SagiCZ1so core.async has things that are handy even though i am not dealing with concurrency?
12:48justin_smithSagiCZ1: it can be useful for code that can be expressed in terms of reading from and writing to queues
12:49clgvSagiCZ1: is that code performance critical?
12:50justin_smiththe basic concept is that all the code is connected by (chan) instances, and all the logic happens by filling and processing queues
12:51SagiCZ1clgv: yes, but i dont think i should optimize it at this point too much
12:53SagiCZ1justin_smith: very interesting
12:53clgvSagiCZ1: no not really.
12:56SagiCZ1clgv: you asked if the code is performance critical, would you have any performance suggestions?
12:57cbryani am not used to paredit yet. just sat there for about 5 minutes trying to delete a bracket
12:58sdegutiscbryan: The point of paredit is that you don't have to delete a bracket.
12:58justin_smithcbryan: haha - C-space / C-w still works :)
12:58sdegutiscbryan: You can delete an s-expression though. Or it's contents. And it'll still be balanced.
12:58cbryanexactly ;)
12:58sdegutisI've been trying to learn paredit.vim lately.
12:58justin_smithsdegutis: you can get in a messy spot if you copy / paste from a non paredit source though
12:58cbryanyep ^ that's what happened
12:59justin_smithcbryan: so yeah, C-space / C-w
12:59sdegutisjustin_smith: Good point. In those cases, I edit parens within a comment, and uncomment then when it's ready.
12:59justin_smithor just temporarily turn off paredit
12:59cbryanjustin_smith: thanks :p
12:59justin_smithsdegutis: interesting approach
12:59sdegutisI find it to be the easiest/quickest way.
12:59sdegutisAnd most flexible.
12:59cbryansdegutis: interesting
12:59justin_smithsdegutis: cbryan you can also use C-q to insert the matching paren
12:59justin_smithso that it's balanced, and thus deletable
12:59sdegutisI haven't found a time when it hasn't worked.
13:13cbryani named my webcrawler project "Parker" and my robots.txt project (to keep Parker in line) "Jameson". it's the little things
13:13sdegutisha!
13:13sdegutis(inc cbryan)
13:13lazybot⇒ 1
13:14cbryanif i'm being honest i was fishing for an inc ;)
13:14sdegutis(inc cbryan)
13:14lazybot⇒ 2
13:15clgvseems not that difficult with sdegutis ;)
13:15sdegutis(inc clgv)
13:15lazybot⇒ 33
13:15cbryannow you're just devaluing it! ;)
13:15sdegutis(dec cbryan)
13:15lazybot⇒ 1
13:15EvanR(dec EvanR)
13:15lazybotYou can't adjust your own karma.
13:15sdegutis(inc EvanR)
13:15lazybot⇒ 1
13:16cbryanno halloween-themed clojure(docs).org? damn
13:17EvanRreminds 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:17sdegutis(dec cbryan)
13:17lazybotDo I smell abuse? Wait a while before modifying that person's karma again.
13:17cbryansdegutis is out of control!
13:17sdegutisNo lazybot I'm just being an active participant in the community.
13:17cbryansdegutis: stop playing with my emotions
13:17sdegutis+1
13:17EvanR(inc lazybot)
13:17lazybot⇒ 32
13:18sdegutis$karma sdegutis
13:18lazybotsdegutis has karma 6.
13:18sdegutisOh nice.
13:19cbryanstarting my new internship monday.. they're a java shop, maybe i can inject some clojure? :D
13:20clgvbetter not in the first week ;)
13:20zachncst22Never hurts to show initiative.
13:20clgvI doubt the empirical truth of that statement
13:20cbryanhaha
13:20sdegutiszachncst22: In this case it may :P
13:21sdegutiscbryan: Why not Scala instead?
13:21sdegutisI hear it's much faster than Clojure, if you're going for speed.
13:21sdegutisWhat's the fastest JVM language?
13:21hfaafbJava
13:21clgvsdegutis: just hack everything together in C and just call per JNI :P
13:21sdegutisclgv: I'd rather write in Lua tbh.
13:22hfaafbJust write it in Go
13:22zachncst22Ugh, JNI
13:22clgvsdegutis: I'll let you know when the next serious post is to be expected from me ;)
13:22SagiCZ1i would use Pascal
13:23zachncst22Go Fortran, it's tons of fun.
13:23EvanRGroovy
13:23zachncst22Clojure is love, Clojure is life.
13:24clgvguess I never use pascal again
13:25SagiCZ1zachncst22: the only thing i hate about clojure is how little i know about it
13:25clgvSagiCZ1: change it ;)
13:26cbryan4clojure taught me the most/fastest
13:26mdrogalisSame
13:26zachncst22SagiCZ1: I agree completely. Which is why it's kicked out Scala as my 'play' language
13:26SagiCZ1clgv: i usually learn by coding..
13:26clgvcbryan: but it leaves knowledge holes you should fill with one of the books^^
13:26bbloom(inc 4clojure) ; looking at other people's answers helped me lots
13:26lazybot⇒ 3
13:28clgvyou can't learn the big picture with 4clojure alone...
13:28mdrogalisJust saying, it's a nice start.
13:29mdrogalisA Datomic equivalent would be fun... :D
13:29clgvyeah, for fast practical experience it is awesome.
13:29the_dankofellows, 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:29SagiCZ1i 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:30justin_smiththe_danko: did you specify any password in your database config?
13:30the_dankoanyone 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:30sdegutishfaafb: phshaw
13:30the_dankojustin_smith: no, seems like we are onto something!
13:30the_dankojustin_smith: (def db "jdbc:postgresql://localhost/webdev")
13:31justin_smith{:classname com.postgresql.jdbc.Driver :subprotocol "postgresql" :host "localhost" :database "webdev" :user "youruser" :password "yourpassword"}
13:31cbryanthe_danko: how are you actually connecting?
13:31cbryanor that :p
13:32the_dankocbryan: execute in clojure jdbc
13:32the_dankojustin_smith: thanks! trying now!
13:32justin_smiththe_danko: or, alternatively, construct the URL with all that info as a string, but easier to use the map form as above
13:33EvanRlispcast = eric normand?
13:33the_dankoevanr: correcto
13:33EvanRok
13:34the_dankojustin_smith: Caused by: java.lang.ClassNotFoundException: com.postgresql.jdbc.Driver
13:34justin_smiththe_danko: correction :classname "org.postgresql.Driver"
13:34justin_smiththe rest should work
13:35justin_smithI was lazy, and I was looking at my mysql config on my most recent project :P did a poor on-the-fly translation :)
13:37the_dankojustin_smith: hmm, missing a required parameter
13:37justin_smithdoes it say which one?
13:38justin_smith:classname :subprotocol :host :database :user :password
13:38justin_smithI specified all of those right?
13:38the_dankoCaused 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:38the_dankojustin_smith: correct
13:39epicherois there a book on debugging clojure yet?
13:39justin_smithI think classname should be a string
13:39justin_smith(it is in my code for postgres at least)
13:39epicheroi always parse name as meaning a string(in my head)
13:43the_dankohmm, maybesubname? i'll get googling
13:43the_dankomaybe :subname i mean
13:44the_dankokeep googling
13:44the_dankothanks again justin_smith
13:46justin_smiththe_danko: here is an obfuscated version of a config that actually works: {:classname "org.postgresql.Driver" :subprotocol "postgresql" :host "127.0.0.1" :database "favoritedogs" :user "user1" :password "xxxx"}
13:47the_dankocfleming: automatic line breaks would really be awesome!
13:47the_dankojustin_smith: thanks, trying it out now!
13:50the_dankojustin_smith: (def db
13:50the_danko {:classname "org.postgresql.Driver"
13:50the_danko :subprotocol "postgresql"
13:50the_danko :user "user"
13:50the_danko :password "pass"
13:50the_danko :subname "//localhost:5432/webdev"
13:50the_danko :unsafe true}) worked!
13:50the_dankojustin_smith: thanks a lot!
13:50justin_smithnp
13:50justin_smiththe_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:51justin_smithI forgot that was in there
13:51the_dankojustin_smith: ha, you led me in the right direction. i wasn't aware of the map form.
13:52justin_smiththe_danko: for extra credit you can throw a :datasource in there with a connection pooling class :)
13:52cbryanyay! now i can scroll irssi with my mouse. the future is now
13:52EvanRthe_danko: jealous of the formatting of that map
13:52the_dankoEvanR: ha, i stole it from here https://github.com/budu/lobos/blob/master/test/lobos/test.clj
13:52justin_smithI am sure there is a dodgy emacs library that does it automatically
13:53the_dankojustin_smith: with hope, cfleming will be rocking this shit soon in cursive!
13:54the_dankothe more times you say something, the truer it becomes
13:54Bronsaalign-cljlet can indent map literals that way
13:54Bronsahttps://github.com/gstamp/align-cljlet
13:54justin_smithBronsa: I knew it! and there is a small chance it isn't even dodgy
13:54Bronsajustin_smith: it works really well
13:55the_dankocfleming: 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:56mmeixLight Table has very good indenting, like it
13:58epicheroI have spent so much time trying out different solutions on vim and emacs for clojure workflow
14:19mdrogalisI'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:20tbaldridgemdrogalis: 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:21tbaldridgemdrogalis: 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:21amalloytbaldridge: (constantly "shallow and trite")
14:21tbaldridge(inc amalloy)
14:21lazybot⇒ 184
14:22cbryantbaldridge: tweetwall
14:22amalloyjustin_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:22mdrogalistbaldridge: Hah, very cool.
14:23mdrogalisI think I'll do that! Thanks!
14:23justin_smithmdrogalis: another possibility: try to predict who will end up following / favoriting / retweeting
14:23cbryanmdrogalis: http://tweetwall.com/ inspiration :p
14:24cbryanwould 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:24justin_smithamalloy: clearly the solution is for everyone to use identical, policy approved, emacs config
14:24justin_smith(nor am I a fan of that kind of indenting btw)
14:24amalloyfor 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:24mdrogalisjustin_smith cbryan: Thanks. :D
14:25dbaschmdrogalis: I did a word cloud generator a while back, just ran it for the word “giants” http://images.diegobasch.com/giants.png
14:25EvanRis this the right place to ask about datomic advice
14:25pandeirowhat 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:25justin_smithmdrogalis: 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:25dbaschmdrogalis: https://github.com/dbasch/twittercloud
14:25amalloyEvanR: i'm pretty sure #datomic is a thing
14:26arrdemmdrogalis: #gamergate what could go wrong
14:26mdrogalisI still dont understand what gamergate is. I tried multiple times :(
14:26mdrogalisBut, not relevant for #clojure I guess.
14:26mdrogalisThanks guys ^ Ill check those links.
14:27mmeixIs there a guide line concerning the order of a function's arguments?
14:27mmeixfor example:
14:27mmeix(defn myfn [x coll] (remove #{x} coll))
14:27mmeixor
14:27mmeix(defn myfn [coll x] (remove #{x} coll))
14:27arrdemmmeix: cols come last typically
14:27cbryanmakes it easier to partial-ize!
14:27amalloyarrdem, mmeix: sequences go last; other kinds of collections usually go first
14:27dbaschthere are examples of both
14:28dbaschstrings usually go first
14:28amalloyarrdem: see, for example, update-in, assoc, etc
14:29mmeixok, is there some rationale behind this, besides partializing, or is this just a stylistic thing?
14:29the_dankoamalloy justin_smith not sure whether just was joking or not but forcing a code formatter on all developers in the company works great!
14:30arrdemstyle and allowing ->> as an idiom on sequence last functions
14:30mmeixah, I see
14:30amalloymmeix: ->> for sequences, -> and the unified update model for other stuff
14:30amalloyeg, it lets you write (swap! x update-in [:people] conj mmeix)
14:30arrdemthe_danko: pre-commits that lint, test and reindent are awesome :D
14:31mmeix(notes term "unified update model")
14:31amalloywhich wouldn't work unless update-in and conj both took their collection argument first
14:32justin_smiththe_danko: forcing everyone to use emacs usually not so great
14:32amalloymmeix: 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:32mmeixaha! thanks
14:32the_dankoarrdem: 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:32the_dankoarrdem: we did not do pre-commit checks though. also i have never heard of lint until now.
14:33the_dankoarrdem: care to elaborate?
14:33arrdemthe_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:34tufthello clojureplex
14:34the_dankoyo tuft!
14:34the_dankoarrdem so you just reject commits instead of autoreformatting?
14:34arrdemthe_danko: sure
14:35Bronsathe_danko: it's more useful to reject commits if the linter returns warnings or if the test fail though
14:35mmeixamalloy BTW: reading flatland.org/useful/ source is a great learning experience for me :-)
14:35the_dankoBronsa: who is this linter fellow everyone ist alking about?
14:35arrdem$google c lint
14:35lazybot[Lint (software) - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Lint_(software)
14:36Bronsathe_danko: http://en.wikipedia.org/wiki/Lint_(software)
14:36arrdem$google clojure eastwood
14:36lazybot[jonase/eastwood · GitHub] https://github.com/jonase/eastwood
14:36the_dankoarrdem Bronsa ha i got that far but thanks!
14:36the_dankoarrdem ill check out
14:36the_dankoarrdem check it otu
14:36arrdem$google clojure cloverage
14:36lazybot[lshift/cloverage · GitHub] https://github.com/lshift/cloverage
14:37arrdemthe_danko: ^ test coverage tool for Clojure
14:38the_dankoarrdem and what did you mean by reindent? reformat?
14:38amalloymmeix: great
14:39arrdemthe_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:39arrdemthe_danko: astyle for Java/C++/C
14:40arrdembbloom: did you take the code format patches?
14:40arrdemlooks like he did
14:43sdegutisGonna tackle Transducers today!
14:43joobussdegutis: don't forget to wear protection
14:46dwmmhas anybody written a comparison of buddy and friend?
14:46dwmmI'm looking to use one of them with liberator and biddi
14:47amalloyhaving 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:48amalloyso, take that for what it's worth
14:50bbloomarrdem: yeah, i merged it and tweaked it a bit
14:51bbloomarrdem: however, i should be clear that gofmt style code convention enforcement is a non-goal
14:51bbloomi'm almost exclusively interested in debugging macros
14:51bbloomalthough i guess it also helps as a starting point for hand tuned re-formatting
14:53dwmmthanks I'll look into it, but I'm hesitant to try it
14:55the_dankocfeming: 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:55the_dankocfleming: 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:56andyfBronsa: 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:57andyfThen 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:57the_dankocfleming: the highlight matching when the cursor is near a paranthesis is great, but the always on rainbow thing could be cool.
14:57andyfDoes t.a.j warn here because the tag is useless/ignored by Clojure?
15:03sdegutisTranducers are still in a beta version of Clojure and therefore not safe to use in production yet right?
15:04justin_smithsdegutis: probably safer than a stable version of mongodb
15:04sdegutis!!!
15:04TimMcoh snap
15:05andyfsdegutis: 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:05mdrogalisWorld Singles seems to run edge everything.
15:06justin_smithin 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:06TimMc"MongoDB: A ship in the harbour is safe, but that's not what ships are for"
15:07TimMc"(ships are for moving fast and breaking things)"
15:07justin_smithTimMc: therefor we invite you to climb on our raft made of twine and truck tires
15:08hiredmanbut ships are but boards, sailors but men.
15:14the_dankoso why do i need parantheses around the anonymous function here?
15:14the_danko(def app (-> routes wrap-params wrap-db (#(wrap-resource % "static")) wrap-server ))
15:15justin_smith,(macroexpand '(def app (-> routes wrap-params wrap-db (#(wrap-resource %
15:15justin_smith "static")) wrap-server )))
15:15clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:15justin_smitherr
15:15justin_smith,(macroexpand '(def app (-> routes wrap-params wrap-db (#(wrap-resource % "static")) wrap-server )))
15:15clojurebot(def app (-> routes wrap-params wrap-db ((fn* [p1__48#] (wrap-resource p1__48# "static"))) ...))
15:15hiredman,(macroexpand '(-> a (fn [])))
15:15clojurebot(fn* a ([]))
15:15hiredman,(macroexpand '(-> a ((fn []))))
15:15clojurebot((fn []) a)
15:15arrdemthe_danko: you don't (def app (-> routes wrap-params wrap-db (wrap-resource "static") wrap-server))
15:15TimMcthe_danko: Because it's actually (fn [...] ...), and what happens to parenthesized forms when you put them in -> ?
15:16the_danko(macroexpand '(-> a f1 (f2))
15:16justin_smiththe_danko: you need a , before that
15:17hiredman,'#(+ 1 %)
15:17clojurebot(fn* [p1__249#] (+ 1 p1__249#))
15:17the_danko,(macroexpand '(-> a f1 (f2))
15:17clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:17TimMc,(-> a #((((((a)))))))
15:17clojurebot#<sandbox$eval322$a__323 sandbox$eval322$a__323@1bd831f>
15:19the_dankoTimMc: so it looks like (macroexpand `(-> a f1 f2))
15:19the_danko is equivalent to (macroexpand `(-> a f1 (f2)))
15:19the_danko=> (-dev-main/f2 (-dev-main/f1 -dev-main/a))
15:19the_danko(macroexpand `(-> a f1 (f2)))
15:19the_danko=> (-dev-main/f2 (-dev-main/f1 -dev-main/a))
15:19the_danko(macroexpand `(-> a f1 ((f2))))
15:19the_danko=> ((-dev-main/f2) (-dev-main/f1 -dev-main/a))
15:20the_dankoTimMc: hmm, i don't know why (f2) is equivalent to f2 but not ((f2))
15:20justin_smiththe_danko: that's just a weird thing about ->
15:21the_dankojustin_smith: ha, ok, well now i know! thanks.
15:21justin_smiththe_danko: a pattern you will see is (#(f % b)) in ->> or (#(f b %)) inside ->, beause this switches arg position
15:21TimMcthe_danko: For convenience, -> allows you to say foo instead of (foo).
15:22justin_smithbut it is better to use as->, or an embedded cal to -> / ->>
15:23TimMc,(macroexpand '(-> a b c))
15:23clojurebot(c (b a))
15:23TimMc,(macroexpand '(-> a (b) (c)))
15:23clojurebot(c (b a))
15:23the_dankojustin_smith TimMc thanks !
15:23TimMc,(macroexpand '(-> a (b 1 2) (c 3 4)))
15:23clojurebot(c (b a 1 2) 3 4)
15:23TimMcthe_danko: ^ This illustrates it.
15:24TimMcThen see hiredman's message above for why #() interacts weirdly with this.
15:24TimMcFinally, see if you can understand why my example above works the way it does: (-> a #((((((a)))))))
15:24TimMcIt's a pathological example, but illustrative.
15:25the_dankoTimMc: 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:25the_dankoTimMc: instead. which works.
15:26sdegutisHow 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:26csd_Magit is pretty neat
15:26sdegutis(inc csd_)
15:26lazybot⇒ 1
15:27the_dankoTimMc: cool, so i think i have the abc part. now onto hiredman.
15:28the_dankoTimMc I love the lessons plan by the way!
15:28justin_smithsdegutis: looks like a forth interpreter
15:28sdegutisbbloom: You wrote a forth interpreter in <=140 chars!?
15:28justin_smithsdegutis: actually yeah, it's a small subset of forth, but it uses forth semantics with a list as a stack
15:29justin_smithsdegutis: where reduce is used to run the program (the words of the program being in the input)
15:29sdegutisThat is so fricken cool.
15:29sdegutisI 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:30justin_smithsdegutis: the idea with forth is words take N words off the stack, do some operation, then put N words back on
15:30bbloomit's more fun to see it with reductions:
15:30justin_smithsdegutis: iterate maybe
15:30bbloom(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:30bbloom,(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:30clojurebot(() (5) (5 5) (25))
15:30justin_smithbbloom: yup, and that does exactly what the forth program "5 dup *" would do
15:30sdegutisCould this be easier with transducers maybe?
15:30cbryanugh, "contact us about pricing." my four least favorite words
15:30sdegutisbbloom: That is just so cool.
15:31justin_smithhaha, transducers are more about perf than ease of programming
15:31sdegutisOh I didn't know that.
15:31sdegutisI am now tempted to embed a forth interpreter somewhere in our website.
15:31Bronsajustin_smith: perf & reusability
15:31sdegutisYeah I thought reusability was the big one.
15:31the_dankoTimMc: I don't feel like it is clicking with the (-> a #((((((a)))))))
15:32the_dankoTimMc: if you're bored. otherwise i'll figure it out. thanks again.
15:32TimMcFirst see what the reader does.
15:32TimMc,'(-> a #((((((a)))))))
15:32clojurebot(-> a (fn* [] ((((((a))))))))
15:32justin_smithBronsa: 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:32TimMcThen see what macroexpansion does:
15:32meliponehello! 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:32TimMc,(macroexpand '(-> a #((((((a))))))))
15:32clojurebot(fn* a [] ((((((a)))))))
15:33TimMc,(macroexpand '(-> a #(a))) ;; a simpler version
15:33clojurebot(fn* a [] (a))
15:33justin_smithmelipone: you can get the source out of the jar if nothing else
15:33clojurebotHuh?
15:33justin_smithmelipone: but you don't need the github location in order to use it if that's what you mean
15:34TimMc,(-> a #(= (a) a))
15:34clojurebot#<sandbox$eval133$a__134 sandbox$eval133$a__134@83c488>
15:34TimMc,((-> a #(= (a) a)))
15:34clojurebot#<StackOverflowError java.lang.StackOverflowError>
15:34TimMcthe_danko: Sorry, my example was bad.
15:35TimMc,((-> a #(a)))
15:35clojurebot#<StackOverflowError java.lang.StackOverflowError>
15:35the_dankoTimMc why are you using a for the function and the argument?
15:35justin_smithmelipone: I think the actual source is linked here http://commons.apache.org/proper/commons-math/download_math.cgi
15:35the_dankoTimMc is that part of the lesson? i assume so. i just don't get why.
15:36TimMcThere's no argument, actually -- I'm just demonstrating that -> is capable of giving a function literal a name. A terrible idea, but interesting.
15:37the_dankoTimMc 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:37TimMc(-> a (fn* [] ...)) becomes (fn* a [] ...); "a" doesn't end up in the body of the fn, because that's not the outermost collection.
15:44meliponejustin_smith: But how do I know what is the clojure interface?
15:44justin_smithmelipone: I don't know that there is on - but you can open the jar you get from clojars, it's a zip file
15:44justin_smiths/on/one
15:48meliponejustin_smith: If there is no clojure wrapper, why is there a clojar package for it?
15:49justin_smithmelipone: I am wondering what is up with that package, checking it out now
15:51justin_smithmelipone: weird, when I specify the dep, it doesn't even seem to download anything....
15:53meliponejustin_smith: it did download something. I'm checking it out now
15:53justin_smithweird, seems like my emacs is misbehaving
15:54meliponejustin_smith: yeah, it's just the apache jar and nothing else.
15:54justin_smithmelipone: yeah, that was my first guess (I am seeing that now too)
15:54justin_smithmy emacs dired for some reason showed me an empty directory the first time... problem on my end clearly
16:20txgruppiHi. 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:21postpunkjustinIANAL, but yes
16:22postpunkjustinClojureScript just compiles to JavaScript, so it's not dependent on Clojure in any particular way
16:22technomancythe compiler is written in clojure, but that's all
16:23justin_smithtxgruppi: a previous employer was able to put clojurescript in production without deploying any clojure
16:23txgruppipostpunkjustin, 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:23justin_smithright
16:23postpunkjustinYeah, your output will be HTML+JS
16:24txgruppipostpunkjustin, technomancy, justin_smith: Thank you all
16:24technomancytxgruppi: 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:24technomancyeven if it's theoretically not required.
16:24justin_smithtechnomancy: I assumed it was more about being able to use cljs in production without deploying clojure itself, I could have misinterpreted
16:24txgruppitechnomancy: the problem is that I can't just change the backend to clojure. Learning clojure will not be a problem
16:25technomancyok, cool
16:26justin_smith"Learning clojure will not be a problem." that's the spirit!
16:27txgruppihauhuahuahua
16:27teslanickDo you have a chant or mantra that I can pass along to my coworkers?
16:27amalloy$timer 30 0 0 hauhuahuahua
16:27lazybotTimer added.
16:28hiredman~suddenly
16:28clojurebotCLABANGO!
16:28txgruppiI 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:29justin_smithtxgruppi: a buddy of mine deploys cljs to backend node
16:30txgruppijustin_smith: nice! does he have any github (or some other public place) project with it?
16:30justin_smithtxgruppi: I'll ask, and let him speak up if he would like to break anonymity :)
16:31txgruppijustin_smith: thx =D
16:36postpunkjustinI'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:36justin_smithpostpunkjustin: a client very picky about implementation, and not very wise about the tech, I think
16:37arrdempostpunkjustin: and you sacrifice access to all the JVM libraries and tooling. No, I agree.
16:37postpunkjustinYeah, I can see how that would happen.
16:37hiredmanit is a silly thing to do
16:37technomancypeople do silly things all the time though
16:38technomancyhttps://en.wikipedia.org/wiki/The_Ministry_of_Silly_Walks
16:38postpunkjustinI actually thought about doing it for something that would run on a Raspberry Pi, since Clojure is a bit much for the hardware.
16:39hiredmandon't get me started
16:39justin_smithpostpunkjustin: I have a beablebone that runs a node webserver by default
16:40justin_smithfor 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:40justin_smith*beaglebone
16:42postpunkjustinYeah, Node is way better than the JVM for serving something like that on "cute" hardware
16:42postpunkjustinesp. when the JVM has to load all of clojure.core
16:42seangrovepostpunkjustin: Gotat go ocaml if that's where you're headed
16:43hiredmanthe jvm was designed for embedded set top boxes
16:43technomancyjust use rackjure if you're low on ram =)
16:44postpunkjustinWoah, hadn't heard of rackjure, but I should have guessed it would happen sooner or later
16:44postpunkjustinI kind of like Hy
16:44postpunkjustinbut I used to write a fair bit of Python
16:44technomancyhy... http://thisotplife.tumblr.com/post/63360807823/mutable-data-structures
16:45postpunkjustinYeah, Clojure's immutable data structures are part of my brain now.
16:48sdegutisbbloom: I'd love to see a full-blown library expanded on your Forth interpreter tweets. That'd rock.
16:49sdegutispostpunkjustin: 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:49postpunkjustinUgh Ruby.
16:50sdegutispostpunkjustin: You prefer Python?
16:53postpunkjustinYeah, but only marginally at this point
17:08toxmeisterhey 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:10justin_smithtoxmeister: ssh upload is turned off, gpg only
17:10hiredmanthe scp deploy method was disabled due to, I think shellshock is what it is being called
17:10hiredmanyou have to use `lein deploy` which deploys via https
17:11toxmeisteryes, using `lein deploy clojars` as usual
17:11technomancy403 indicates that it's an http failure though
17:11hiredmanOh
17:12technomancytoxmeister: I'm getitng the same thing
17:12technomancylooking into it
17:12toxmeisterweird, just tried once more the same... and it worked this time!!
17:13toxmeistertechnomancy: thanks, but use your time more wisely :)
17:13technomancybut it's still failing for me
17:15justin_smithtoxmeister: technomancy: http://i.imgur.com/Y6hqNQP.png
17:17toxmeistertechnomancy: yeah, happening again for me too (there i was hoping to have a release friday...)
17:17technomancyxeqi: any changes to clojars recently?
17:18toxmeistertechnomancy: is there a way to get more verbose debug info for these deploy requests?
17:18toxmeisterbit like `curl -v`
17:19technomancytoxmeister: you can try setting LEIN_DEBUG=y
17:19technomancyor maybe just DEBUG=y
17:20technomancynothing all that helpful though
17:23toxmeisterhmmm... 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:24toxmeistermaybe that error can be ignored?
17:24cflemingthe_danko: You can already align map items like that in Cursive: Settings->Code Style->Clojure->Align map items
17:24xeqitechnomancy: nothing
17:24xeqitechnomancy: theres some minor restructuring refactorings on master, but nothing has been deployed in months
17:25cflemingthe_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:25technomancylogs are rather unhelpful for this
17:26justin_smithcfleming: double-rainbow-parans-what-does-it-mean
17:26erikcwI 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:27the_dankocfleming cfleming: awesome, thanks!
17:27justin_smitherikcw: which clojurescript repl do you have running?
17:27xeqilooks like maven-metadata.xml didn't get updated, wonder if url that being split wrong
17:27the_dankocfleming maybe the rainbow hsould be default? also i agree on the brigher colors. very helpful still. thanks. just turned them on
17:27erikcwjustin_smith: with figwheel (using the chestnut lein template)
17:28xeqinot sure why that would have changed since aug tho
17:28erikcwjustin_smith: weasle with figwheel — sorry
17:29justin_smitherikcw: you should be able to run M-x cider, and then pick the port that weasel is running on
17:29justin_smithcider-jack-in starts a process, cider just finds one to connect to
17:29justin_smithor maybe it is called cider-connect now
17:30lambdahandsIs there a way to create a core.async timeout function that accepts microseconds instead of milliseconds?
17:33amalloylambdahands: (fn [t] (timeout (quot t 1000)))
17:33toxmeisterxeqi: 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:33amalloynot a useful answer, i'm sure, but the best one available
17:33erikcwjustin_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:33dbaschamalloy: you could build your own with the high resolution timer
17:34dbaschwho knows how accurate it would be
17:35justin_smitherikcw: have you tried the code suggested on the weasel readme? https://github.com/tomjakubowski/weasel
17:35justin_smiththe whole (cemerick.piggieback/cljs-repl ...) thing
17:36dbasch,(let [[a _ b] [(System/nanoTime) (Thread/sleep 1) (System/nanoTime)]] (- b a))
17:36clojurebot1144357
17:36dbasch&(let [[a _ b] [(System/nanoTime) (Thread/sleep 1) (System/nanoTime)]] (- b a))
17:36lazybot⇒ 14949110
17:36erikcwjustin_smith: yeah — I get an “Address already in use” error
17:36justin_smitherikcw: when specify a different address?
17:37justin_smith*then
17:37erikcwjustin_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:38jcsimserikcw: aside from the lack of a 'cljs.user' prompt, are you sure you're not in a cljs context when you connect?
17:38justin_smitherikcw: I am sorry, I don't know.
17:39justin_smitherikcw: so you opened a cljs context in a repl, and then when you connect to the repl in emacs you get clj?
17:40badylhi, 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:40erikcwjcsims: Looks like you’re right — I am in a cljs context, I just didn’t know it! OOPS!!
17:41arrdemso.. an enum with keywords as values?
17:41badyland I am wondering how it can be done in a most clear way
17:41jcsimserikcw: good! if that wasn't the case, I was out of suggestions ;)
17:41justin_smithbadyl: you can use sorted-set-by, and any function that predictably returns -1 0 or 1 when provided with two keywords
17:41erikcwjcsims: I assumed they were running under different threads or something
17:41erikcwjcsims: thank you
17:41erikcwjustin_smith: thank you!
17:42badylarrdem: yes, I have maps where there is an entry with keyword values as enums
17:42jcsimserikcw: no problem!
17:43arrdemamalloy: so why are you not a fan of your own defenum macro?
17:43justin_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:43clojurebot#{:h :a :b :c :d ...}
17:43dbaschkeywords are comparable
17:44dbaschwhat’s wrong with the default (lexicographic) sort?
17:44amalloyarrdem: the one that's like the first project i ever pushed to github?
17:44arrdemamalloy: back in 2010 yeah that one
17:45dbasch,(compare :a :b)
17:45clojurebot-1
17:45amalloyarrdem: you want me to look further than https://github.com/amalloy/enum/blob/master/src/enum/core.clj#L3 ?
17:45arrdemmaybe this isn't the _right_ defenum, but I think in principle a defenum is reasonable.
17:45arrdemamalloy: no need I'm wiping blood away too
17:46badyllet'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:46justin_smithdbasch: I am aware they are comparable, but I assumed he wanted some non-default sorting
17:46badylI know I can use just (compare :a :b) but I need a specific order, not lexicographics one
17:46justin_smithbadyl: then use sorted-set-by as I showed above, with a function that provides the right comparison result
17:46dbaschnever mind, it wasn’t clear to me from the question
17:46dbaschbut in that case yeah, just define your own compare function
17:47lambdahands@amalloy Thanks! So timeout takes a quoted list with two elements?
17:47justin_smithbadyl: .indexOf on an array may help (subtracting two indexes to get pos / 0 / neg
17:47justin_smith
17:47justin_smith)
17:47badyldbasch: 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:47amalloylambdahands: that quot is "quotient". it's a facetious suggestion that you divide microseconds by a thousand to get back to milliseconds
17:47badylbut it seems I have to write one
17:48dbaschlambdahands: do you need sub-millisecond resolution? I guess that’s the question
17:48amalloybecause there's nothing i know of that takes microseconds, nor any compelling reason to need it
17:48amalloybadyl: https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L243 is kinda close
17:49amalloyyou can't use it directly but you can perhaps adapt the idea
17:49dbasch&(let [[a _ b] [(System/nanoTime) (Thread/sleep 1) (System/nanoTime)]] (- b a))
17:49lazybot⇒ 18028774
17:49dbaschthat’s 18 ms
17:49lambdahands@amalloy: Ah, of course.
17:50lambdahandsdbasch: Yes, that's what I'm looking for.
17:50amalloy&(let [[a _ b] [(System/nanoTime) (Thread/yield 1) (System/nanoTime)]] (- b a))
17:50lazybotjava.lang.IllegalArgumentException: No matching method: yield
17:50amalloy&(let [[a _ b] [(System/nanoTime) (Thread/yield) (System/nanoTime)]] (- b a))
17:50lazybot⇒ 15650228
17:50lambdahandsIt's for a live performance using overtone's Open Sound Control library.
17:50amalloy&(let [[a _ b] [(System/nanoTime) [] (System/nanoTime)]] (- b a))
17:50lazybot⇒ 8380435
17:51badylamalloy: thanks it is really close
17:51badyljustin_smith: your solutions is also similar
17:51dbasch,(let [[a b] [(System/nanoTime) (System/nanoTime)]] (- b a))
17:51clojurebot12407
17:52dbasch&(let [[a b] [(System/nanoTime) (System/nanoTime)]] (- b a))
17:52lazybot⇒ 7417257
17:52badylthanks guys for the ideas. It's my first interaction with clojurians on IRC and you were very helpful
17:52dbaschdoes lazybot run on an abacus?
17:52justin_smithbadyl: thanks
17:53dbasch, (- (System/nanoTime) (System/nanoTime))
17:53clojurebot-818
17:53dbasch& (- (System/nanoTime) (System/nanoTime))
17:53lazybot⇒ -7569558
17:53lambdahandsHmm, so System/nanoTime is the answer then?
17:53justin_smith,(let [order [:c :b :a]] (- (.indexOf order :b) (.indexOf order :a)))
17:53clojurebot-1
17:54justin_smithbadyl: the above could be easily made a comparison function, with your order of keys specified in a vector
17:54EvanRis there a function to convert keyword to string without the prefixed :
17:54justin_smithEvanR: name
17:54justin_smith,(name :a)
17:54clojurebot"a"
17:55justin_smith,(map name ['a "a" :a])
17:55clojurebot("a" "a" "a")
17:55justin_smithI like the above :)
18:05amalloydbasch: lazybot has some weird stuff in its interop-sandboxing code
18:06amalloyi don't remember what the deal is anymore, but it makes interop really slow
18:06dbaschamalloy: is it sending everything to the NSA? :P
18:06arrdemdbasch: this is IRC they get everything anyway
18:07dbascharrdem: you can be lazy and paranoid :P
18:33amalloyis there some version of max that uses compare instead of >?
18:34hiredman,(doc max-key)
18:34clojurebot"([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."
18:34hiredmansort of
18:35amalloyright, which doesn't actually do that. it's fine if you can map your stuff onto integers
18:35hiredman,(doc compare)
18:35clojurebot"([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:35hiredmanisn't that would compare does?
18:35hiredmanwhat
18:36hiredmanOh
18:36hiredmanright
18:37hiredmanwell, wait, I think that should be fine
18:37TEttinger(doc sort)
18:37clojurebot"([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:38TEttingerso sort and get the last?
18:38hiredmanmax works are two arguments, so you don't need everything mapped to some known fixed set of numbers, it should work
18:38hiredman(unless max-key just calls the key once)
18:38hiredmanon two
18:38hiredmanyou just need to be able to come with numbers for every two things, not for everthing
18:39amalloyhiredman: i don't understand. max-key calls (f x) and (f y), then compares them
18:39amalloyit doesn't call (f x y), which would be the compare interface, and exactly what i wanted
18:39hiredmanfoo, right
18:40hiredmanI was not thinking about compare correctly of course
18:41amalloyi'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:42TEttingeramalloy, because you can sort and get the first or last?
18:42amalloyTEttinger: no, that is outrageous
18:42amalloyperforming an O(n*log(n)) operation for no reason when O(n) will do is not something you should do
18:42TEttingerfine
18:44amalloyi 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:44amalloythat sounds like me
18:44dbaschamalloy: one more thing you can stick in useful
18:45TEttinger(doc compare)
18:45clojurebot"([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:46dbaschsomething like
18:46dbasch(defn max-by [f a b] (if (pos? (f a b)) a b))
18:47dbaschand reduce by that, or whatever
18:48TEttinger,(defn max-compare [coll] (reduce #(if (pos? (compare %1 %2)) %1 %2) coll))
18:48clojurebot#'sandbox/max-compare
18:49TEttinger,(max-compare [2 3 [1 2 3 4]])
18:49clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>
18:49TEttingerwell I dunno how that works
18:51hyPiRion,(compare 3 [1 2 3 4])
18:51clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>
18:51TEttingertype-independent manner my ass
18:53hyPiRioncompares numbers and collections in a type-independent manner => ints and doubles can be compared, lists and vectors can be compared
18:54hyPiRionIt's not like comparing a number to a collection suddenly made sense.
18:54technomancyeeeeeh
18:54technomancyI can see value in a universal comparator
18:55technomancyit doesn't have to make sense across types so much as be consistent across types
18:58andonilssonWeird thing. Was using core.async channels for dealing with cards (you know, poker etc). So I tried: (onto-chan (chan) deck-of-cards)
18:58andonilsson...but the channel returned from onto-chan never contained anything.
18:59andonilssonInstead I had to do something like:
18:59andonilsson(def c (chan))
18:59andonilsson(onto-chan c deck-of-cards)
18:59andonilsson...and then I could pull my cards from channel c.
19:04nathan7andonilsson: (doto (chan) (onto-chan deck-of-cards))?
19:04nathan7,(macroexpand `(doto (chan) (onto-chan deck-of-cards)))
19:04clojurebot(let* [G__27 (sandbox/chan)] (sandbox/onto-chan G__27 sandbox/deck-of-cards) G__27)
19:04nathan7shit, I gotta go refactor a whole lot of code using that trick
19:04andonilssonor, even better in my case: (to-chan deck-of-cards)
19:05andonilssonFound it while browsing the source for onto-chan
19:06justin_smithyeah, doto is kind of handy sometimes
19:07JohnJJhi guys I want to add the JDBC jar to a local repository, I've tried Archivia without success, what do u suggest?
19:07andonilssonstill, 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:07justin_smithJohnJJ: how are you managing your deps? if it is not lein you should probably switch.
19:08technomancyJohnJJ: depends on why you want a local repository, really. lots of ways to do it.
19:08JohnJJjustin_smith, technomancy: I'm using lein, and I'm using Nightcode as an IDE
19:09justin_smithJohnJJ: and using the usual .m2/ cache doesn't suffice for local repository?
19:09justin_smithare you serving a dep for multiple users or machines?
19:10JohnJJjustin_smith: I've just tried that but couldn't get how the folder structure should be, can I just put the .jar there?
19:10technomancyJohnJJ: what are you trying to accomplish?
19:10technomancyusually archiva is used to cache dependencies to protect against network failures and stuff
19:10justin_smithJohnJJ: the normal thing is to declare the dep, such that lein finds it automatically
19:11technomancyor for private stuff, not jdbc drivers
19:11JohnJJtechnomancy: just trying to get my clojure app to connect to SQL Server
19:11justin_smithJohnJJ: add [mysql/mysql-connector-java "5.1.6"] to your deps in project.clj
19:12justin_smithand you probably want org.clojure/java.jdbc too
19:12justin_smithoh way you didn't say mysql
19:12JohnJJjustin_smith: it is SQL Server from Microsoft, not Mysql
19:13justin_smithhttp://claude.betancourt.us/add-microsoft-sql-jdbc-driver-to-maven/ install it locally, then declare a dep
19:13JohnJJjustin_smith: I've lein installed but not maven, should I install maven then?
19:14justin_smithJohnJJ: technomancy: there is a lein command for that, right?
19:14technomancyyeah, check out the second arity of deploy
19:14JohnJJjustin_smith: that's my confusion, how can lein run without maven
19:15justin_smithJohnJJ: it uses a bunch of the same libs
19:17justin_smithtechnomancy: I'm looking at lein help deploy now - what is the magic repo string for "into .m2"
19:17technomancyjustin_smith: file:///home/me/.m2/repository
19:17justin_smithtechnomancy: cool
19:18justin_smithJohnJJ: so that's the simplest way (other than installing maven and copy/paste from that web site I guess)
19:20JohnJJjustin_smith, technomancy: I'm trying to install maven right now
19:26technomancywow, so the MS DB honestly does not publish any official jdbc deps?
19:27justin_smithtechnomancy: all I could find were workarounds via local install
19:27technomancyinconcievable
19:28mlb-In SKI combinator calculus, is the Clojure `doto` macro analagous to the K combinator?
19:28technomancymlb-: not really, SKI doesn't have side-effects
19:29technomancyI would say K is more like constantly
19:29mlb-ah, that's fair
19:29technomancybut neither functions nor macros map strictly to combinators I guess
19:30justin_smithtechnomancy: 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:30mlb-I ask because I've recently been abusing `doto` inside of thread first/last macros
19:30amalloymlb-: how is that abuse? doto and -> go together like bacon and eggs
19:30justin_smithmlb-: doto inside thread-last seems a bad plan
19:30amalloyit's a lot harder in ->>
19:31justin_smithnow if we had doneby
19:31justin_smith(which would be like doto but taking the thing as the last arg)
19:31JohnJJjustin_smith: sad MS is sad, I'm progressing with Maven right now
19:31justin_smithJohnJJ: cool
19:32mlb-I've been doing things like (->> stuff (map transform) (filter predicate?) (#(doto % (->> count (spy :info "Count of stuff")))))
19:32justin_smithmlb-: aha - as-> may help there
19:33mlb-and then continuing the chain, unaffected by the doto's transformation on the collection
19:33technomancy(doto prn) in -> is the best
19:33justin_smithyes it is
19:33Bronsatrue
19:34mlb-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:36mlb-thanks for the reassurance, everyone =]
20:11whodidthiswhats an easy way to forward all messages from one channel to another
20:13justin_smithwhodidthis: looks like that is what pipe does
20:13whodidthisoh cool
21:18weii 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:21justin_smith,(reduce (fn [[mx sum] v] (let [update (+ v sum)] [(max update mx) update])) [0 0] [1 2 -30 8 12])
21:21clojurebot[3 -7]
21:22justin_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:22clojurebot([0 0] [1 1] [3 3] [3 -27] [3 -19] ...)
21:22andrewhrthat was fast :O
21:22andrewhrI was just tinkering on repl…
21:23justin_smithandrewhr: it took me a few tries
21:24andrewhrhahaha ok. I will keep up practing my clojure-fu
21:24muraiki_you could also use http://clojuredocs.org/clojure.core/reductions
21:24justin_smithmuraiki_: see my second example
21:24muraiki_oh
21:24muraiki_haha
21:24muraiki_didn't read that far yet T_T
21:25justin_smithwell I didn't use reductions to find the max - simpler to just update in one pass
21:25justin_smiththough I could have used reductions of sum, and taken the max of that
21:25muraiki_yeah, that's the approach I was thinking of
21:25muraiki_my clojure-fu is weak though
21:25andrewhrsame approach here
21:26justin_smith,((juxt #(apply max %) last) (reductions + 0 [1 2 -30 8 12]))
21:26clojurebot[3 -7]
21:26justin_smithactually the reductions / max version is elegant
21:26justin_smithbut does an extra walk, which is against the first criteria :)
21:26justin_smithactually it walks the full length 3 times
21:29hyPiRionspeaking of, is there anyone else besides me finding a function à la this useful?
21:29hyPiRion,(defn aside [& fs] (fn [vs x] (mapv #(%1 %2 x) fs vs)))
21:29clojurebot#'sandbox/aside
21:29hyPiRion,(reduce (aside + - max) [0 0 0] (range 10))
21:29clojurebot[45 -45 9]
21:30justin_smithoh, very nice
21:31justin_smithit captures a pattern I often do, where I want to do more than one reduction on the same sequence
21:31hyPiRionyeah, I tend to do that a lot too – It's like juxt on reductions
21:32weithanks guys. so my sequence of numbers is the result of a transduce
21:32weiis there any benefit to writing the reduction as the final transduce step?
21:33weiand is that even possible?
21:33justin_smithin that case, you should be able to compose the other ops with the transduce