#clojure logs

2014-12-02

02:02schrottigreetings
02:04schrottii'd like to perform thread-safe memcached operations with spyglass, thus want to ask if the following approach leads to this: get the data to be worked on from memcached and reference it with a ref, perform all the work synchronous on the ref and write the final ref value back to memcached
02:05schrottiwant to write it as idomatic as possible, thur avoiding explicit locking, that would allow me to perform i/o operations in the locked section
02:08andyfschrotti: By thread-safe you mean you want to read one or more values from memcached, calculate modified values, and write back the modified values, and be guaranteed that no other thread in the same JVM process can read any of those same values while you have them ?checked out'?
02:08andyfAnd you plan on there being at most one JVM process, but perhaps many threads in that JVM process?
02:10lain1Hello. I'm trying to use quil fun-mode to write a simple game. key-pressed is [old-state event] -> new-state and I can get the key that was pressed out of the event. However key-released is just old-state -> new-state so I'm confused how I'm supposed to know which key was released. Anyone have experience with quil?
02:12schrottiandyf: correct
02:15andyfschrotti: I don?t know if there is a way to do that. memcached seems to have little or nothing in the way of multi-key atomic operations
02:16lain1Hmm, looks like there's a (raw-key) function which gets the most recently pressed or released key. Bit clunkier than getting it as a parameter but I'll use that. O well
02:18schrottiandyf: yea i know, in a python implementation of the api i set a lock-key in memcached to tell other jvm process (different hosts) this one is being worked on, which actually also should be sufficient for thread within on process on the same jvm
02:18schrottibut within python i locked that critical sections within the code too
02:21schrottinow it seems there's still the time between setting the lock-key in memcache, getting the data i want to fiddle with and ref it.
02:23andyfschrotti: If there is only one JVM process, why do you need the data in memcached?
02:23andyfSo the data is still there if the JVM process dies?
02:24schrottiandyf: there will be multiple jvm processes at some point in time
02:24schrottiwant to use memcache for session data
02:25andyfSo you need a way to prevent multiple JVM processes from accessing overlapping sets of key/value pairs in memcached in parallel? I don't think refs in one JVM process can help you there.
02:26schrottiandyf: thats why i write a key to memcache, that tells the other processes that a certain key is currently being worked on
02:28andyfschrotti: Using a memcached cas operation? I don't think normal get/set operations on single keys will prevent races there.
02:29dysfunsound like you need a distributed lock mechanism (like redcache, but for memcached) or redis (which supports limited transactionality)
02:29dysfuns/redcache/redlock/
02:31schrottiandyf, dysfun thanks for the input i take a look at them
02:32andyfschrotti: Example of race for a simple try at using a special key value as a makeshift lock: Every process tries to write to key "global_lock" with a value equal to the name of the keys they want to work on atomically. Process 1 reads "global_lock" and sees it is empty. Then process 2 does. Process 1 writes "global_lock" the set of keys "a, b, c" that it wants access to. Then process 2 does.
02:33andyfNeither has any way to look at the memcached contents and tell that it isn't the only one.
02:33andyfYou could run something like Baker's mutual exclusions algorithm on top of memcached, but there must be a better way.
02:34dysfuni suspect redlock relies on redis transactions
02:34dysfunbut it's been a while since i poked at redis
02:35dysfuni'm sure it's findable with enough googling
02:35andyfIf you want transactions, it seems best to use a database that provides them.
02:36dysfuni think some projects don't have the option of choosing postgres
02:37schrottii could use postgres for it
02:38dysfunbut it's session data, right?
02:38schrottibut trying to get away from due to future demands and also just using it to store session data later is kind of overkill
02:39andyfdysfun: Why do you say that about postgres? You mentioned transactions being available in redis, so that statement confuses me.
02:39dysfunokay, start again. stop talking about building your implementation and start talking about what you want to achieve :)
02:40dysfunandyf: redis transactions are fun. we use redlock for many operations. if you want real transactions, you use something with real transactions
02:40schrottidysfun: session handling for a distributed service
02:41schrottiandyf: and about your example i could use the memcache add function, that only adds a key if it doesn't already exists
02:41schrottibut theres still network delay
02:41dysfunbut it returns a value to indicate whether it added the key?
02:42schrottiyes it'll return true or false respectively
02:42dysfunwell, that's your mutex then
02:43dysfun(if (set-lock-key!) ... (show-error))
02:44andyfas long as memcached doesn't age out that mutex
02:45andyfdysfun: I've not used redis for transactions. When you say they are fun, do you mean they don't really work as transactions in some way? Or that they are inconvenient to use for some kinds of transactions?
02:46dysfunandyf: you know how clojure STM works? redis does a similar thing. except without automatic retry. you'll be wanting carmine to help with that
02:55schrotti(dotimes [i 10] (future (while (false? @(mc/add mc-client "lock" 5 i))) (let [r (mc/get mc-client "test") new (inc r)] (mc/set mc-client "test" (* 60 60 24) new) (mc/delete mc-client "lock"))))
02:56schrottithat works
02:57andyfschrotti: Unless "lock" is ever aged out of the cache, but perhaps you can prevent that from happening.
02:58schrottiandyf: the lock needs to age out, what if the thread fails at some point and doesn't release the global lock?
02:58schrottiall the other processes, threads would deadlock in this case
02:58andyfWhat if it ages out when the process still thinks it has the lock?
02:58schrottiandyf: true
02:59andyfAgain, there may be ways to prevent that, but they probably rely on limiting how long a process can hold the lock, in real-time
02:59schrottithat's why it only performs as less operations as possible
02:59andyfJust please don't make someone lose property or other valuables if it doesn't work :)
03:00schrottihehe
03:00andyfI'm assuming we aren't talking about human lives or health.
03:01andyfIf it's just "ah, someone may have to reload their browser window when this fails", all kinds of hacks have been done.
03:02schrottiandyf: it certainly is for health related sensor data
03:02andyfthen I'm scared you are asking these questions.
03:04schrottiandyf: everyone starts somewhere, been only 1 year in the coporate world, and because it's about health data, i want to do the best
03:04schrottithat's why i reimplenting the api, that i wrote previously in python, which is a mess because it was the first rest-api i ever wrote in python. trying to learn from mistakes
03:04andyfI don't mean you should not ask questions. I mean, I hope all of this design goes through review of people who know the failure modes of transactional systems before it becomes part of a product, and they suggest something else.
03:05andyffailure modes of someone trying to implement transactions, but incorrectly, I mean.
03:05schrottiandyf: unfortunately that won't happen :/. that's why i have to do my best.
03:06schrottiand in this case it is the session handling for a mobile client
03:06andyfso what happens if some of this health related sensor data is reported incorrectly?
03:06schrottithus it does not interfere with the critical point of sending or receiving data
03:07andyfI mean, if this code doesn't implement locking correctly, are we saying they have to hit reload on a mobile client and delay getting the correct data, or does it mean they get incorrect data?
03:08schrottiit means they would have to reload/relogin on the mobile client, thus possibly receiving data delayed
03:08andyfIt wouldn't ever happen that someone accidentally gets data from a different session, for example?
03:09schrottiandyf: nope
03:10andyfI do hope that is true, but if you do not see the failure modes of your example code above, how did you reach the conclusion that only delay of correct data is possible?
03:10dreamPilothey any CLJS people here ?
03:12schrottiandyf: if the client didn't receive a session token i due time, that it can use to get the data, it can retry this operation. there's is no specific/critical health data related to any session.
03:13schrottithe session is just a means of validating a given user and password for a mobile client, that uses the token to ask for data
03:14schrottiand because the lock expires after a couple of seconds, the client will be able to aquire a session at some point
03:15schrottibut it does not interfere with receiving any critical data
03:16andyfSorry if I'm not being more helpful -- I would if I had more experience with what you are working on. Perhaps someone else will read this and join in or contact you.
03:17schrottiandyf: that's totally fine, you already provided me with valuable thoughts for the brain
03:17schrotti+enough
03:23Empperiis there any kind of less css support for clojure as a library, not a leiningen plugin?
03:23EmpperiI'd love to use garden but our web designer guys don't really want or have time to learn clojure so it's not an option
03:24Empperiwe can live with precompiled less css which is then saved as .css file and pushed to git, but really would like not to do it
03:25Empperiso an optimal solution for us would be a garden like library but which preprocesses less files
03:26schrottiandyf: if you're interested -> http://neopythonic.blogspot.tw/2011/08/compare-and-set-in-memcache.html this one provides an example on how to avoid deadlocks and race conditions. and also by limiting the amount of retries, a thread/process performs to acquire the lock.
03:26kenrestivoEmpperi: there's a lein-less but i haven't used it
03:26kenrestivohttp://crossclj.info/ns/lein-less/latest/project.clj.html
03:27Empperiyeah, but that's just a npm wrapper which compiles less files to css
03:27Empperiso not really what I asked for
03:27EmpperiI don't want to generate that css into disc
03:27EmpperiI just want to serve it
03:28Empperiso in development mode the css is generated everytime from scratch when it is requested and in production mode the generated css would be cached
03:28EmpperiI've done less compiler wrappers in java and I could do that in Clojure too but don't feel like it right now if there is an existing solution out there
03:32SagiCZ1why cant case have default value?
03:33SagiCZ1,(case 1 0 "yes" :default "no")
03:33clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: 1>
03:34andyfSagiCZ1: It can have a default: http://clojuredocs.org/clojure.core/case Leave out :default
03:34SagiCZ1 ,(case 1 0 "yes" "no")
03:34clojurebot"no"
03:34Empperi,(case 0 "yes" :default "no")
03:34clojurebot"no"
03:34SagiCZ1andyf: thank you
03:35SagiCZ1Empperi: i think that is wrong
03:35Empperiyes I realized that myself too :)
03:35Empperibeen sleeping way too little lately
03:35SagiCZ1np
03:35Empperi8 week old baby at home, need I say more...
03:36SagiCZ1congratulations
03:36Empperithanks
03:36schrottiEmpperi: congrats
03:36Empperithanks
03:36schrottimine could come anytime now ^^
03:36Empperi,(repeatedly "thanks")
03:36clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
03:36TEttingerEmpperi, baby bjorne, have a baby be a fashion statement
03:36SagiCZ1not that making babies is particularly hard
03:36Emppericrap, too little sleep :D
03:36Empperi,(constantly "thanks")
03:36clojurebot#<core$constantly$fn__4346 clojure.core$constantly$fn__4346@1e7d0fe>
03:36TEttinger,(repeat 10 "you're welcome")
03:36clojurebot("you're welcome" "you're welcome" "you're welcome" "you're welcome" "you're welcome" ...)
03:37andyfSagiCZ1: For males it isn't -- I would recommend not making such a statement to a female :)
03:37SagiCZ1haha true that
03:38ddellacostaanyone know how to do an "update ... returning" using clojure.java.jdbc?
03:38ddellacostaseancorfield: ping
03:47ddellacostafolks, what does fn* do?
03:50andyfddellacosta: It is the guts of the implementation underlying clojure.core/fn
03:50andyfLike the macro clojure.core/fn, but without many of the options
03:51ddellacostaandyf: thanks. I'm struggling to understand what it is doing all over c.j.j, for example here: https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L695
03:51ddellacostalooks like it's consistently getting called w/metadata {:once true} but not sure what that means
03:52ddellacostaI find this codebase quite confusing, I feel like it uses a very specific style which I haven't seen elsewhere
03:53andyfIn that particular case, it is defining a function that is bound to symbol exec-and-return-keys, which is later called inside of with-db-transaction.
03:53ddellacostaandyf: that much I get--I just don't understand why it is used at all. What does {:once true} do?
03:53andyf{:once true} has something to do with allowing the function to clear local variables after use, I think. In any case it is a time and/or memory optimization that shouldn't affect correct operation unless you are holding on to the head of a large sequence.
03:54ddellacostaandyf: I see, thanks for the explanation
03:54ddellacostayeah, it would make sense if most of the arcana in this lib is optimization stuff
04:02SagiCZ1how do i make a list from map keys and vals? {:a 0 :b 2} --> (:a 0 :b 2)
04:04SagiCZ1,(zipmap {:a 0 :b 2})
04:04clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core/zipmap>
04:05SagiCZ1,(flatten {:a 0 :b 2})
04:05clojurebot()
04:10andyfddellacosta: Relevant Google group thread: https://groups.google.com/forum/#!searchin/clojure/malloy$20once/clojure/Ys3kEz5c_eE/3St2AbIc3zMJ
04:10SagiCZ1andyf, sorry to bother you but do you have any idea how to achieve what i asked for?
04:10ddellacostaandyf: thanks so much!
04:11ddellacostavery helpful
04:11andyfSagiCZ1: I think (interleave (keys m) (vals m)) may be correct
04:12SagiCZ1andyf: perfect, thank you!
04:12SagiCZ1(inc andyf)
04:20andyfmaybe more cryptic: (mapcat identity m)
04:23hellofun`andyf did you say core/fn was a macro??
04:23hellofunkmaybe i misread
04:23andyfyes, it is.
04:24cfleminghellofunk: Yes, it is
04:24hellofunkandyf officially isn't it a special form?
04:24cflemingAlong with defn, let, and many others.
04:24andyfclojure.core/fn is a macro implemented with defmacro. It expands to a special form fn*
04:25andyfNot all, but many things that you often think of as special forms actually are implemented as macros
04:25hellofunkinteresting. the (doc fn) just says it is a special form. usually the doc shows if something is a macro
04:25andyflet -> let*
04:25cflemingreify -> reify*, deftype -> deftype*
04:25andyfTry (source fn)
04:25cflemingThe * forms are actually interpreted by the compiler.
04:25cflemingWell, compiled is perhaps a better word.
04:26hellofunkwell that is quite interesting.
04:26hellofunklisten, andyf, i would like to thank you. thank you most earnestly for brining this matter to my imminent attention
04:26cfleming,(macroexpand '(fn [x] x))
04:26clojurebot(fn* ([x] x))
04:27cfleming,(macroexpand '(let [a :a] a))
04:27clojurebot(let* [a :a] a)
04:27andyfIf you'd like a complete list of things that are 'really special':
04:28andyf,(keys clojure.lang.Compiler/specials)
04:28clojurebot(& monitor-exit case* try reify* ...)
04:28hellofunkandyf i already know that list
04:28hellofunkWall-E, blueberries, Belgian beer. those are the things that are "really special"
04:45kralnamaste
04:47TEttinger,(rand-nth ["Hey" "Yo" "Hi!" "Hola"])
04:47clojurebot"Hola"
04:47clgv:P
05:04schmirI'd like to automatically coerce a joda localdate object to an sqldate in clojure.java.jdbc. is that possible?
05:09klokbaskeHey! Any ring users here?
05:09andyf~anyone
05:09clojurebotJust 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 ..."
05:10klokbaskeI'm trying to find my stacktrace when ring returns an error 500
05:10klokbaskeBut it's seemingly nowhere to be found
05:11weavejesterDo you have anything to catch the exception, e.g. Cider, or to display the stacktrace, e.g. wrap-stacktrace?
05:12klokbaskeI have cider running, and I've added wrap-stacktrace
05:13klokbaskeI've checked various buffers in emacs but nothing there either
05:14roderykCould someone explain what I'm doing wrong with this snippet of core.async [cljs]? The browser is giving me a most unhelpful message: http://pastebin.com/H6G1dNs5
05:19weavejesterklokbaske: Which version of Ring are you running?
05:19klokbaske1.3.1
05:21klokbaskeweavejester: 1.3.1
05:23weavejesterklokbaske: Okay, so wrap-stacktrace will catch any Throwable... What does the webpage/command line look like when the error occurs?
05:23weavejesterAre you running it locally?
05:24klokbaskeweavejester: yes I'm running locally. Nothing in the commandline. I'm just doing a curl, and I only get a header with a code 500
05:24weavejesterklokbaske: Is wrap-stacktrace the last middleware you use?
05:25klokbaskeweavejester: yes, last one.
05:26weavejesterklokbaske: That should catch any throwable then, and even if it didn't, you should see at least the exception printed.
05:26weavejesterklokbaske: Which adapter are you using?
05:26Kneivaschmir: I think you can get java.util.Date from LocalDate. Can that be used to create clojure.java.jdbc.sqldate?
05:26klokbaskeweavejester: I'm using jetty
05:27weavejesterroderyk: I can't see anything wrong with that, unless you're missing a require somewhere?
05:27weavejesterklokbaske: Okay... that's odd. Jetty's usually pretty good about reporting errors.
05:28weavejesterklokbaske: I think I'd need to see your project. I can't think of any reason why you wouldn't be seeing an error.
05:28weavejesterklokbaske: Unless your code is returning an empty 500 response explicitly.
05:29klokbaskeNope, it's not. I have a homemade handler that cannot seem to handle a list, but does handle a map. I wonder if my handler swallows the error
05:29klokbaskeI think I'll try disabling it.
05:30schmirKneiva: sure. but I was hoping for an automatic conversion.
05:40trisshey all. I'm following this heroku/clojure tutorial. everything goes well until i set up the postgresql server on this page: https://devcenter.heroku.com/articles/getting-started-with-clojure#provision-a-database
05:41trissi get this error upon running the code:
05:41trissorg.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of clojure.lang.Keyword. Use setObject() with an explicit Types
05:41triss value to specify the type to use.
05:41hellofunkif i want a recursive fn in a let binding, does it recur on the let var name, or on a name defined in the fn itself? i.e. (let [a (fn b [] .. (b ..))]) -- is that (b ..) correct or would (a ..) suffice?
05:42roderykweavejester: thanks; was accidentally using an old version of core.async
05:42trissdoes anyone know how to set the type of data? I presume I need to tell postgresql to expect a string or specify to clojure what typ the thing is its recording.
05:45clgvhellofunk: you can just use `recur`
05:46clgvhellofunk: or did you mean non-tail recursive?
05:47clgvhellofunk: non-tail recursive #(let [a (fn b [x, s] (if (pos? n) (b (dec n)) (recur (dec n) (* n s)))] (a 5 1))
05:47hellofunkclgv recur would work in my case. but suppose it is not tail recursive? i always get confused which name a fn in a let refers to -- the name given to fn or the name assigned in let
05:47clgv,(let [a (fn b [x, s] (if (pos? n) (b (dec n)) (recur (dec n) (* n s)))] (a 5 1))
05:47clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
05:48vijaykirantriss: Can't you use type hints ? ^String etc. ?
05:48clgv,(let [a (fn b [x, s] (if (pos? n) (b (dec n), (* n s)) s)] (a 5 1))
05:48clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
05:48clgv,(let [a (fn b [x, s] (if (pos? n) (b (dec n), (* n s)) s))] (a 5 1))
05:48clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: n in this context, compiling:(NO_SOURCE_PATH:0:0)>
05:48vijaykirantriss: http://clojure.org/java_interop#Java%20Interop-Type%20Hints
05:48clgv,(let [a (fn b [x, s] (if (pos? x) (b (dec x), (* x s)) s))] (a 5 1))
05:48clojurebot120
05:49clgvhellofunk: `a` is not bound to the function while the function is defined
05:49hellofunkclgv ok so inside the fn, the name of "a" is not used
05:49hellofunkgot it
05:49clgvhellofunk: yeah, it either is not bound at all or bound to a previous value in the lexical scope
05:53hyPiRionAssume I have the syntax-quoted form `(let [f# foo g# baz] (bar f# (expr-with g#))), but bar is a macro I want to expand at syntax-quote time. What's the best way to handle this?
05:55daniel__trying emacs again with evil-mode, cider, clojure-mode
05:55daniel__.clj keep opening in fundamental mode, so no syntax highlighting
05:57vijaykirandaniel__: did you get it to work ? or is that a question ?
05:57daniel__https://github.com/danielstockton/dotfiles/blob/master/emacs
05:57daniel__its a question
05:57vijaykiranokay - you might need a hook
05:58vijaykirandaniel__: similar to line 35
05:58daniel__can't find anything like that mentioned in any of the package docs
05:59trissvijaykiran... unfortunately that didn't work
05:59trissI specified a type hint for the record function
06:00vijaykirandaniel__: the automode is in clojure-mode
06:01vijaykirandaniel__: try adding a require ? perhaps the clojure-mode isn't auto-loaded in your setting
06:01daniel__vijaykiran: that worked
06:01daniel__cheers
06:03hellofunkhyPiRion interesting, you are saying you want it to expand, and then a additional expansion after it expands, due to the macro. is that not what happens?
06:09hyPiRionhellofunk: it happens, but I need to print the form out, then read it back in in a different environment
06:09hyPiRionwhich doesn't have the same namespaces available
06:11hyPiRionI found out that it wasn't sufficient to solve my problem anyway, so I'll have to handle this differently.
06:21martinklepschhow can I create a string like "\/some\/uri.html"?
06:21martinklepsch,(str "\/some\/uri.html")
06:21clojurebot#<RuntimeException java.lang.RuntimeException: Unsupported escape character: \/>
06:21martinklepsch,(str "\\/some\\/uri.html")
06:21clojurebot"\\/some\\/uri.html"
06:22martinklepschI render this through chesire's generate string and it turns up in the result with two backslashes per slash
06:30clgvhyPiRion: at syntax quote time? can you give an example what that would do?
06:31clgvmartinklepsch: print it and you see the actual characters
06:32martinklepschclgv: that's what I thought too but when I pass it to chesire I still end up with two backslashes even though println shows only one
06:32clgvmartinklepsch: backslashes are used to escape special characters like newline "\n" but hence backslash itself needs to be escaped
06:32martinklepschclgv: data.json has an option for this, I'll try this now
06:33clgvmartinklepsch: maybe it is using `pr` instead of `print` ?
06:33TEttinger,(pr "\\/some\\/uri.html")
06:33clojurebot"\\/some\\/uri.html"
06:34TEttinger,(print "\\/some\\/uri.html")
06:34clojurebot\/some\/uri.html
06:34TEttingerpr is so it can be consumed by clojure, as if in source
06:34martinklepschclgv: could be
06:35hellofunkhow do you check if something is an atom, such as + :a varname, etc? I was looking for atom? but it's not there. I could check if something is not a collection like (not (coll? ..)) but that seems verbose
06:35clgv,atom?
06:35clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: atom? in this context, compiling:(NO_SOURCE_PATH:0:0)>
06:35clgv,(instance? clojure.lang.Atom (atom 0))
06:35clojurebottrue
06:36hellofunkclgv that is equally verbose. shouldn't have to query the implementation's class name
06:36hellofunkby the way, by atom I am not referring to a reference type, rather a classic lisp atom. symbol? seemed close, but it doesn't cover everything of course
06:37hellofunkis this the only way? (defn my-atom? [a] (not (coll? a)))
06:37clgvhellofunk: oh you can just ask whether it is not one of the collection types
06:39clgvhellofunk: since there might be arbitrary many collection and atom classes - this predicate is impossible to write. would be different if all the collections share a common interface.
06:39hellofunkmakes sense
06:39clgvhellofunk: so for clojure data you might be able to write that predicate for given clojure version
06:40clgvhellofunk: you could also first detect the non-atoms you are interested and everything else is classified as atom - depends on your use cases whether this is appropriate
06:40hellofunksure
06:41hellofunki think common lisp has something like atom? which is what i was looking for. no bid deal.
06:43clgvhellofunk: it is probably easier over there since all collections are based on lists
06:43clgvso non-list is atom
06:46hyPiRionclgv: I want something that can transform `(let [f# 1] (.. f# toString hashCode)) into '(clojure.core/let [f__1 1] (. (. f__1 toString) hashCode))
06:46hyPiRionThat only expands "..", in this case
06:48CookedGryphonDoes anybody have any suggestions for how to test core.async with timeouts?
06:49CookedGryphonI want to set the test up to say behave as if these events came in and then this timeout fired etc
06:49CookedGryphonobviously without actually waiting for the timeout to fire
06:49clgvhyPiRion: just tried that syntax quote. is the problem that `toString` and `hashCode` get a namespace prefix?
06:50clgvhyPiRion: or do you need the "expanded name" of the gensym?
06:55clgvah. selective expansion
06:55clgvhyPiRion: you could do that with zach tellmans walking lib?
06:55clgvhyPiRion: riddley
06:57clgvhyPiRion: if I remember correctly you can also manipulate tools.macro's macroexpand-all to not expand given forms.
06:58clgvhyPiRion: it has an internal machanism therefore but does not provide an option to initialize its data from the macroexpand functions
07:03hyPiRionclgv: I know about it, just wondered if there was an easy way out
07:03hyPiRionfigured out a better solution in the end either way
07:03clgvok. what did you do?
07:06hyPiRionI avoided the problem altogether :)
07:10clgv:)
07:37noncomhave anyone tried clojure monger lib? i want to update an existing document, adding fields to it.. the only way i have found is to 1) download the document, 2) merge it on my side, upload the merged doc
07:37noncomis there any way to perform the merge on the db side ?
07:38noncomthe (update) functions seems like it should be able to do that, but i am not sure how to make it work.. currently it simply replaces the document
07:47vijaykirannoncom: is monger.collection/update what you are using ?
07:47noncomvijaykiran: yes, this is it
07:47vijaykirannoncom: can you gist the code that isn't working?
07:48noncomhere: https://www.refheap.com/94284
07:49noncomsee, if i do not first fetch an existing document, then merge it with data manually, then it will simply *replace* the doc in the db
07:49noncomso i have to manuall y merge the maps
07:49vijaykiran1 min
07:49noncomi have tried playing with the :upsert param but it does not change much..
07:49noncomok
07:49vijaykiranwhy are you using :upsert ?
07:50vijaykiranah, okay :)
07:50noncom:)
07:51edw,(+)
07:51clojurebot0
07:51clgv,(*)
07:51clojurebot1
07:51noncom,(-)
07:51clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/->
07:51noncom:(
07:52clgvhaha
07:52noncombooom! )
07:52hyPiRion- is not a monoid
07:52hyPiRion,(->)
07:52clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/->>
07:52hyPiRion,(->>)
07:52clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/->>>
07:52noncomheeh
07:53noncom,(<)
07:53clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/<>
07:53clgvhyPiRion: operators are no monids ;)
07:53noncom,(bit-and)
07:53clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/bit-and>
07:53clgv+o
07:53hyPiRionclgv: this is true
07:53noncomis (bit-and) a monoid ?
07:53noncomlooks like np
07:53noncomno
07:54noncom,(bit-or)
07:54clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/bit-or>
07:54noncomoh well..
07:54noncomok ok
07:54clgvnot every function needs a zero arity. ;)
07:55Deraennoncom: http://clojuremongodb.info/articles/updating.html#using_set_operator
07:55hyPiRion,(apply distinct? []) ; :-(
07:55clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/distinct?>
07:56vijaykirannoncom: I think you need to use $set
07:56vijaykirannoncom: just like you do on mongo shell
07:56vijaykirannoncom: https://github.com/michaelklishin/monger/blob/master/src/clojure/monger/operators.clj#L116
07:57clgv,(distinct [])
07:57clojurebot()
07:57clgv;)
07:57hyPiRionI am still confused about that one.
07:57clgvyeah, update-in was pretty bad for empty paths as well
07:58noncomDeraen, vijaykiran: oh wow, right! $set does the right thing!
07:58noncom(distinct (list))
07:58noncom,(distinct (list))
07:58clojurebot()
07:58noncom,(distinct (vector))
07:58clojurebot()
07:59clgvdistinct is lazy, hence the list like return
07:59clgvdistinct is a good candidate for a transducer
08:00noncom(apply distinct? (list)) cannot operate on that argument because (distinct?) has no meaning over an empty collecion i think
08:01hyPiRionBoils down to: Are all elements in an empty collection different?
08:01hyPiRionI can verify that no element in an empty collection is equal to another element, but I don't know if that equates to the above.
08:02noncomi am sure there is a pocket of math that has already considered this case..
08:03hyPiRionFrom wikipedia: "Two or more things are distinct if no two of them are the same thing."
08:03clgvhyPiRion: from a math point of view that shoud evaluate to true
08:03hyPiRionwhich makes (distinct? x) sort-of weird
08:05noncomhttp://www.thefreedictionary.com/distinct
08:05noncommeanings 2, 3 and 5 from the first group for the adj are applicable :)
08:06noncommeaning 1 is not :D
08:06clgvnoncom: meaning (1) - every item of the empty list is distinguishable from all the others
08:07noncomclgv: how do you know that if you've never ever seen them? :D
08:08clgvnoncom: that's the point, there is no element in the list, hence that predicate is true
08:08noncomwell, i can't say more except for that it gives creeps to me :D
08:08noncoman empty set is the ultimate true..
08:09clgvnoncom: not really if your are interested in existence of elements with properties it is false ;)
08:11noncomso, anyhow, it turns out that emptiness is the truth..
08:12noncomisn't that from buddhism or somewhere.. ?
08:12clgvsounds like "zen" ;)
08:13noncomso now i am sure all that whole zen or buddhism thing is just a way to experience the groups theory in person
08:17l3dxI tried to mash together some of these snippets -> https://github.com/james-henderson/chord but I'm not able to fetch the message from the server. is this because the samples are simplified, or should it be possible without go-loops?
08:24clgvl3dx: there is an example project. does that work?
08:25l3dxhaven't tried it, but it uses go-loop
08:28l3dxthat's probably what I want though, but as this is my first go at core.async I wanted to take baby steps
08:29l3dxcombining the client send / server send snippets might not even make sense :)
08:34clgvl3dx: well you can consider starting from a working small project as baby steps as well. you can start to alter that project to what you want bit by bit
08:35l3dxyeah, sure :)
08:59puredangerBronsa: you around?
09:07crispinhi everyone!
09:08crispinI have a question: What is the difference between binding and let
09:08crispinother then the binding binds the args in parallel, while let does them one at a time
09:08crispinother than that... is there any difference?
09:08crispinwhen would I use binding instead of let?
09:10clgvcrispin: binding is for thread local variables
09:11clgvcrispin: those named similar to "*foo*" declared with metada ^:dynamic
09:11llasram`binding` binds a new value to an existing Var (usually a top-level persistent thing) for the dynamic, thread-local scope of the `binding` form
09:11llasram`let` creates a new local lexical identifier for a value
09:15stuartsierraMore fundamentally, with `let` only code within the text body of the `let` can see the symbols. With `binding`, the values are visible to any code inside the body of the `binding` AND any functions called from there.
09:16Bronsapuredanger: hi
09:17clgvcrispin: you can use `binding` only with names that can be resolved to existing variables
09:18noncom|2who can explain that:
09:19noncom|2,(def bs (.toBytes "heeeey" "utf-8"))
09:19clojurebot#<CompilerException java.lang.IllegalArgumentException: No matching method found: toBytes for class java.lang.String, compiling:(NO_SOURCE_FILE:0:0)>
09:19noncom|2oops
09:19noncom|2,(def bs (.getBytes "heeeey" "utf-8"))
09:19clojurebot#'sandbox/bs
09:19noncom|2(.-length bs)
09:19noncom|2,(.-length bs)
09:19clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: length for class [B>
09:19noncom|2why no matching field ?
09:19noncom|2how to access length ?
09:20opqdonut,(alength (.getBytes "heeeeey" "utf-8"))
09:20clojurebot7
09:20opqdonut,(doc alength)
09:20clojurebot"([array]); Returns the length of the Java array. Works on arrays of all types."
09:20opqdonutI think count works also
09:20opqdonut,(count (.getBytes "heeeeey" "utf-8"))
09:20clojurebot7
09:20opqdonutbut is less efficient
09:24nonubyif my clojure 1.6 simple web apps depends on compojure (https://github.com/weavejester/compojure/blob/master/project.clj) and I dont use an :exclusions in project.clj does this mean that both clojure 1.6 and clojure 1.5.1 are loaded and thus nearly double startup time (given jvm alone startup really is neglible nowdays)
09:25weavejesternonuby: No, only one version of the package is loaded.
09:25nonubywhich is the top level one in my web app project.clj?
09:26weavejesternonuby: The one that's chosen is the one "closest" to your project file. So anything in your project file will be preferred, then first-level dependencies, then second-level dependencies and so forth.
09:26nonubyso you only specify exclusions if you suspect two sibling dependencies at same closest level might be battling over a specific downstream dependencies
09:27weavejesternonuby: Right, or if a closer dependency is overriding a newer but further away dependency.
09:32trissso lets say i want to write a library for myself and have no intention of putting it on clojars]
09:32trisshow do i add the library to my dependancies in project.clj if its just a bundle of local files?
09:33kungitriss: you can use toolk like apache archiva and create your own maven repository
09:33kungitriss: or you can use lein install to install it into your local maven repository and just use it in your project.clj
09:34trissah so lein install means i can then just stick the libs name in my project.clj and get on with things?
09:35kungitriss: yes
09:35trisssplendid...
09:35kungitriss: oh yes
09:35trissI'll be serving my app up on heroku
09:35trissany one know how would i make sure the library makes it up there when i do a git commit?
09:49hellofunkamalloy are you around?
09:49hellofunkguess not.
09:49crispinclgv llasram stuartsierra: thanks. will experiment
09:50justin_smithit's very early west coast time right now - he'll likely be awake in a couple of hours
09:51hellofunkjustin_smith i just realized that. thanks, i forgot what time it is there in u.s.
09:53puredanger(inc Bronsa)
09:54puredangerlazybot sleeping?
09:55hyPiRion~lazybot
09:55justin_smithmust be knocked offline
09:55clojurebotlazybot is a lazybut
09:55justin_smithI have a login on that box, but I don't think I have perms to restart it
09:55FriedBobYou don't get a name like lazybot by doing work.
09:55puredangerwell anyhow, thanks to Bronsa for knowing too much about how AOT works and explaining it to me
09:57noncom|2i need to publish an existing jar to clojars
09:57noncom|2i have no pom for it
09:57noncom|2can anyone tell me what to do ?
10:02llasramnoncom|2: for your .-length q from earlier: the Java `array.length` syntax is Java syntactic sugar for a JVM array-length operation. There's no actual .-length property, which is why that Clojure syntax doesn't work
10:04llasramnoncom|2: For deploying an arbitrary jar to Clojars, you can use maven: http://maven.apache.org/guides/mini/guide-3rd-party-jars-remote.html
10:04llasramWith e.g. https://github.com/ato/clojars-web/wiki/pushing as your destination repo
10:07noncom|2llasram: so the only way to get a correct pom is to use mvn ?
10:08hyPiRionnoncom|2: you can make one from lein too, using lein pom. But you'd probably have to use mvn to deploy
10:09hyPiRionnoncom|2: A better solution is to ask the original author to publish it.
10:09noncom|2it is actually the dropbox official java drivers
10:10noncom|2they just don't have them on clojars..
10:10noncom|2i fear they won't be quick enough to react also..
10:11hyPiRionnoncom|2: https://www.dropbox.com/developers/core/sdks/java ? That one's already deployed
10:11stuartsierrahttp://search.maven.org/#search%7Cga%7C1%7Cdropbox
10:11stuartsierraThe Maven world is much bigger than Clojars :)
10:11hyPiRion[com.dropbox.core/dropbox-core-sdk "1.7"]
10:12hyPiRion1.7.7, rather.
10:13noncom|2oh!
10:15noncom|2btw, as a question for the future, can i fetch jars from maven repos other than clojars ?
10:16noncom|2there must be a lein project param for that ?
10:16kunginoncom|2: there is
10:16noncom|2oh ok, then in case of the situation, i will try that too
10:16kunginoncom|2: the :repositories key
10:17hyPiRionnoncom|2: maven central is bundled by default, btw
10:17hyPiRionClojure is put there, for example.
10:20deadghostI feel dumb typing (in-ns 'project.core) and (in-ns 'project.other-other-ns) all the time
10:21deadghostand switching back and forth via typing
10:21deadghostis there something more alt-tabish
10:22llasramdeadghost: your editor integration should provide something
10:22llasramdeadghost: what are you using?
10:22deadghostemacs
10:22llasramWith CIDER?
10:22deadghostyes
10:22llasramcider-repl-set-ns, by default bound to C-c M-n
10:27deadghosthttp://i.imgur.com/9fW0xw9.png
10:27deadghostwhyyyy
10:28llasramBecause ztellman is hilarious
10:29Glenjaminhaha
10:36hyPiRionobligatory http://aphyr.com/media/context.html
10:37llasramOh is that the ztellmen presentation slide generator?
10:37hyPiRionyes
10:38clgvhyPiRion: seems not business ready, there are no charts ;)
10:38tim___I got "despite our best efforts, optimization is mutable", true dat.
10:39llasram"abstraction supercedes essence"
10:39llasramI can see how one could argue that
10:40hyPiRion"macro is a function monster"
10:44EvanRparenthetically, ALEPH => DERRIDA -?> DECOMPLECTION
10:45EvanRreferential transparency assumes infinite resources, this guy is off putting even without audio
10:47Glenjaminyou know those are random, right?
10:47EvanRthe last one is not
10:47Glenjaminoh right
10:47EvanRthis attitude, i think i am beginning to grok, and be able to reproduce in isolation
10:48Glenjamini was fairly sure he said lazy evaluation assumes infinite resources
10:48EvanR"dont try to do anything right because startup 1 out of 5234 ended up with way too much workload"
10:48EvanR"and failed"
10:49llasramEvanR: I think you're missing a lot of context
10:49EvanRdont worry about the other startups which just failed for other reasons, and start ups that succeed and do not ever encounter the google-sized problems
10:49EvanRllasram: XYZ is contextual, oh no, i forgot to right that one down
10:50EvanRits not a presentation without being melodramatic, i think this gets in the way of real world problems (for most problem solvers)
10:51justin_smithEvanR: he is explicitly talking about what you do when you hit performance limits. If you don't hit those limits, you obviously don't need that advice.
10:51EvanRobviously!
10:51EvanRif only any job i ever had thought that was obvious
10:52EvanRgranted i didnt invent google or youtube
10:53eraserhdIs it possible to use a clojar from a maven project? How would one set the groupId and artifactId for something that advertises itself as '[ring-mock "0.1.5"]?
10:54justin_smithEvanR: I'm actually a big fan of the pragmatism in ztellman's stuff (and the same pragmatism in Clojure core). Purity is nice, but you should make a note of performance issues when your code is in every user's bottleneck (and with the lang, or a good lib, it will be)
10:54llasrameraserhd: The group-id is the same as the artifact-id
10:55llasrameraserhd: It should work fine, just adding clojars as a repository
10:55EvanRjustin_smith: if this is about clojures implementation or design specifically, then nevermind
10:56eraserhdllasram: Ah, thanks.
10:59tbaldridgejustin_smith: EvanR: once, over drinks, I Rich said something that stuck with me: "don't assume that some optimization that works well for a megacorp will work well for you"
10:59hellofunki have a compojure route like this: (route/resources "/") in my resources/public i have /images/image.png. when i run this locally, the image routes and appears fine. when i deploy to heroku, it is a broken link. any ideas?
11:00tbaldridgeI think the example was SPDY, it may save hundreds of thousands for Google, but it's an utter waste of time for a site with just a few servers.
11:00weavejesterhellofunk: Which version of Ring/Compojure are you using?
11:00hellofunkweavejester compojure 1.1.8
11:01hellofunkweavejester but why would it be a versioning issue if it works fine on my local hosted with the same version as it is when deployed to heroku?
11:02weavejesterhellofunk: Well, if you're up to date then it's easier to debug. I don't need to think about whether you might be hitting a known bug.
11:03EvanRtbaldridge: i wish, when faced with suggestions for web-scale killer hacks, i had some sort of simulation or model that i could run and see if it could make a damn of a difference, rather than relying on my reputation or badass demeanor to prove a point to someone who shouldnt believe me at all
11:03hellofunkweavejester well its a production app so we don't update too quickly without our own testing. i suspect there is something else going on here.
11:04weavejesterhellofunk: Maybe. Sometimes production setups are different enough to development setups to make a difference. What happens when you access the image hosted on Heroku? A 404? A 500?
11:04EvanR,(some #{'a 'b 'c} ['e 'f 'g])
11:04clojurebotnil
11:04weavejesterhellofunk: Are you starting from an uberjar or Leiningen? Are you using lein ring or lein run?
11:04EvanR,(some #{'a 'b 'c} ['e 'f 'b])
11:04clojurebotb
11:05tbaldridgeEvanR: not sure I understand
11:05hellofunkweavejester it's a 404
11:06hellofunkweavejester i am running on heroku which i think uses uberjar
11:06hellofunkweavejester locally i am just starting the server with jetty from repl
11:06weavejesterhellofunk: Try building the uberjar and seeing if that works or contains the file?
11:07EvanR,(some #{'a 'b 'c} 'b)
11:07clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>
11:07hellofunkweavejester i must admit i have never built an uberjar before, have not had the need. i will lookup how to do this (I have no Java background)
11:07weavejesterhellofunk: It's just "lein uberjar"
11:07hellofunkweavejester then how do i inspect its contents?
11:08weavejesterhellofunk: If Heroku is using an uberjar, it'll just use that command.
11:08weavejesterhellofunk: jar -tf foo.jar
11:08weavejesterhellofunk: Or just unzip it. Jars are zips.
11:08hellofunkweavejester thanks it is building now.
11:08justin_smithweavejester: hellofunk: emacs or vi will open the insides of jars as if they were directories and let you open the files inside
11:09justin_smiths/vi/vim
11:09hellofunkweavejester it creates both a standalone as well as snapshot, which is the one i am interested in?
11:09weavejesterhellofunk: The standalone just contains all of the dependencies. You want the normal jar.
11:10weavejesterhellofunk: Come to think of it, "lein jar" would have worked as well if all you wanted to do was look at the jar's content.
11:11hellofunkweavejester the file is in the jar under public/images as expected.
11:12weavejesterhellofunk: If you execute the uberjar (the standalone one) with "java -jar", does it work as expected?
11:13weavejesterhellofunk: And does the image have the right headers? Content type, etc.?
11:13hellofunkweavejester actually i think i found the issue. one moment i shall update.
11:15fairuzHi guys. I require a library called clojurewerkz.ogre.core. I did check their source code and this ns do exist. But in my repl, it says java.io.FileNotFoundException: Could not locate clojurewerkz/ogre/core__init.class or clojurewerkz/ogre/core.clj on classpath:
11:15fairuzAny suggestions? thanks
11:16justin_smithfairuz: on github it doesn't exist in the current version https://github.com/clojurewerkz/ogre/tree/master/test/clojurewerkz/ogre maybe you are looking at the wrong version of the source
11:16hellofunkweavejester so the image name is quite long and one character was the wrong case. apparently this is forgiven when launching to localhost for some reason, while it is not forgiven when launching from heroku. not sure why that would be, but glad I found it.
11:17weavejesterhellofunk: Are you developing on a mac?
11:17hellofunkweavejester: yes
11:17justin_smithhellofunk: osx? case insensitive file systems suck
11:17weavejesterhellofunk: The default mac file system is case insensitive, while Heroku likely uses Linux, and is case sensitive
11:17EvanRits not case insensitive
11:18hellofunkso guys, i'm curious. you are saying the case sensitivity of the OS trumps the web server software? weavejester, justin_smith
11:18justin_smithEvanR: what isn't?
11:18justin_smithhellofunk: not the OS. The filesystem.
11:18fairuzjustin_smith: hm I'm confuse. But in src/clojure/clojurewerkz/core there's core.clj. Is this not it?
11:18EvanRffs i dont have my mac
11:18weavejesterhellofunk: The web server is built on the filesystem.
11:18justin_smithif the filesystem is case insensitive, it gives you the same file regardless of case changes
11:19justin_smithfairuz: that would be clojurewerks.core.core
11:19eraserhdHrmm, is there a built-in way to convert a bean to a map?
11:19justin_smithfairuz: but I don't see that file in the repo anywhere
11:19justin_smitheraserhd: bean
11:20justin_smith,(bean (java.util.Date.))
11:20clojurebot{:day 2, :date 2, :time 1417537095208, :month 11, :seconds 15, ...}
11:20fairuzI'm using this release (2.5.0.0) https://github.com/clojurewerkz/ogre/tree/c00351d0e08e9b34d0e62f4654c74f13b9608313
11:20EvanRhow did i survive in an office full of OSX for two years without running into a problem with this case insensitive filesystem oO
11:20hellofunkvery interesting, fellas. Now OSX does offer the ability to set the drive to a case sensitive system, so maybe I should have done that when I partitioned it. weavejester justin_smith
11:20fairuz***src/clojure/clojurewerkz/ogre
11:21justin_smithfairuz: are you sure lein is giving you that exact version of the lib?
11:21justin_smithfairuz: we have at least established that some versions of ogre don't have the core ns
11:21hellofunkthese are the popular options: Mac OS Extended, Mac OS Extended (Journaled), Mac OS (Case-sensitive), and Mac OS (Case-sensitive, Journaled) any other Mac devs, what do you use on your system?
11:22fairuzjustin_smith: I can just check in .m2?
11:22justin_smithfairuz: lein deps :tree
11:22Glenjamini tend to create a case sensitive partition for shared dev stuff
11:22weavejesterI use the default case-insensitive filesystem, but run tests on a Linux box.
11:22justin_smithfairuz: or, while lein is running, look at the output of ps x to see the classpath, which will include the path to the specific jar it is using in the running process
11:22Glenjaminhaving two files with names that differ only by case sucks
11:23weavejesterThere are some who develop against vagrant to be as close as possible the production environment.
11:23justin_smithGlenjamin: I think his issue was that the file was referred to in another file with mixed case
11:23weavejesterBut I've never found it to be that huge an issue.
11:23Glenjaminah right, deploying to case sensitive
11:24eraserhdjustin_smith: Thanks! I thought there was, but brain fart.
11:24justin_smithGlenjamin: so things work locally because fs is insensitive, break remotely where case sensitive
11:25Glenjaminyeah
11:26fairuzjustin_smith: I have [clojurewerkz/ogre "2.5.0.0"] in lein deps :tree
11:27justin_smithfairuz: well, that's weird
11:27fairuzjustin_smith: I'm using instarepl of LightTable if it makes any difference
11:28justin_smithyeah, if you are getting the right version of the dep but the namespace isn't found, I have no explanation for that.
11:32fairuzhmm this is weird
11:34justin_smithfairuz: did you verify via the process listing that that is the version in the classpath of the running instance?
11:37fairuzjustin_smith: It's not in the classpath from the ps x
11:37fairuzThere's another one that is not in the classpath too, but I can use it just fine.
11:38fairuzThis further confuses me :D
11:41ordnungswidrigfairuz: what does clojure.java.classpath/classpath return?
11:41hellofunkamalloy i got a question for you about 4clojure
11:42hellofunkwell, i guess you're not around, my bad.
11:42justin_smithhellofunk: stull not 9 am yet west coast time
11:42hellofunkjustin_smith lol yep.
11:44brucehaumanseangrove: when javascript is reloaded ala figwheel the source maps and corresponding source doesn't seem to be reloaded.
11:44fairuzjustin_smith: there's this entry -> #<File /home/vagrant/.m2/repository/clojurewerkz/ogre/2.5.0.0/ogre-2.5.0.0.jar>
12:31Glenjaminbrucehauman: thanks for following that up btw
12:31Glenjaminbeen liking figwheel so far
12:31Glenjaminused it for a clojurescript intro workshop, mostly "just worked"
12:33brucehaumanthanks man! trying to put a bunch more effort into it this week
12:34Glenjaminhow feasible do you think it'd be to work as lib rather than a lein plugin?
12:34Glenjamini had a few headaches trying to get something similar to chestnut, where the repl/server/figwheel are all in the same process
12:35Glenjaminhttps://github.com/defshef/defshef12 what i ended up with, adding the repl listener into the ring handler namespace
13:05l1xjustin_smith: do you remember the last week convo about using (do all (pmap ...))
13:05l1xactually it is 10x faster than doseq
13:05l1xso yes it is worth to do (doall (pmap (.... even if you are in a thread
13:06SagiCZ1 hi.. when i do (last (take 10 (iterate foo init))) the foo never gets executed, whats wrong?
13:06justin_smithl1x: cool
13:06justin_smith,(last (take 10 (iterate + 1)))
13:06SagiCZ1,(last (take 10 (iterate inc 0)))
13:07clojurebot1
13:07clojurebot9
13:07SagiCZ1it works here.. i dont understand
13:07justin_smithis foo lazy internally?
13:07SagiCZ1it has conj....
13:09SagiCZ1but it doesnt even get called.. i have debug print right at the beginning
13:10justin_smithdo you know that the thing invoking it gets called?
13:11justin_smithand if it is in a thread, are you directly using its terminal, or is it an environment like cider or fireplace where the default root binding of *out* may not be immediately visible?
13:12justin_smitheg. cider creates *nrepl server foo* which gets some misplaced print output
13:15justin_smithSagiCZ1: oh, actually it's the *nrepl-server foo* buffer that gets it - you can see it with (.start (Thread. #(println "hi")))
13:16SagiCZ1i need to investigate this more.. seems really weird, i will come back later if i still cant figure it out
13:47SagiCZ1,(println "100")
13:47SagiCZ1,(println 100)
13:47clojurebot100\n
13:47clojurebot100\n
13:47SagiCZ1ok this was the problem.. i thought i had the same parameters
13:47SagiCZ1,(take "10" (range 12))
13:47clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>
13:48SagiCZ1the exception got swallowed somewhere
14:07hellofunkis anyone here using the cursive plugin for intellij?
14:09nullptrhellofunk: going out on a limb here, but i think cfleming is probably using it...
14:10SagiCZ1hellofunk: i am using it extensively
14:11SagiCZ1cfleming is the author and frequents this channel too
14:11hellofunki was curious if cursive provides function arg and arity hints for clojurescript code?
14:11SagiCZ1hellofunk: not sure.. works for clojure though
14:12hellofunkemacs does this for clojure too, but for cljs it seems to be hard to find this feature
14:16seancorfieldddellacosta: you pinged me last night - did you figure out the answer?
14:17SagiCZ1if i want to build executable jar with leiningen, do i have to specify all namespaces to be :aot in project.cls?
14:18llasramSagiCZ1: Just the :main namespace, which also needs to :gen-class
14:18SagiCZ1llasram: cool
14:18SagiCZ1thanks
14:21SagiCZ1when trying to run the executable jar i get NoClassDefFoundError clojure/lang/IFn
14:27SagiCZ1nevermind, it creates two jars, works like a charm
14:32hellofunkwhat happened to the 2014 State of Clojure survey results? they were apparently taken offline https://cognitect.wufoo.com/forms/state-of-clojure-2014/
14:32nullptrhttp://blog.cognitect.com/blog/2014/10/20/results-of-2014-state-of-clojure-and-clojurescript-survey
14:33hellofunknullptr thanks i guess they have a broken link on their other blog post
15:09justin_smithso I have a problem that is likely solved by checking if the arg is an instance of AFn, but before I decide on that, what is implementing AFn supposed to convey?
15:10justin_smithmy main criteria is I want to match protocol methods, multimethods, and functions, but not symbols and keywords
15:10justin_smithand AFn lets me differentiate between those
15:11ordnungswidrigjustin_smith: can you give more context? Why do you need to differentiate?
15:11justin_smithsince all of them implement IFn, but only the former list are AFn
15:12ordnungswidrigI would not rely on that fact and check if it's a symbol or keyword if it's what you want.
15:12justin_smithordnungswidrig: callable (all of them) vs. a thing that is meant to be called with args
15:12justin_smithother things are callable but not in the list of things I want either
15:12ordnungswidrigwhat about (fn [] "boo!")
15:12ordnungswidrigit's callable but without args.
15:12justin_smiththat is fine
15:13justin_smithmy "with args" thing was sloppy, sorry
15:13ordnungswidriggive me more context
15:13stuartsierra`AFn` is mostly an implementation detail; not intended to convey anything.
15:13ordnungswidrigwhy not (not (or (symbol? x) (keyword? x)))
15:14justin_smithordnungswidrig: it is a router for handling requests, and so far we had a whitelist of "if it's a function, use that, otherwise resolve the symbol or use the var" etc. but I would like something a bit more resilient (so that for example a user can supply a multimethod or protocol function and expect it to work)
15:14ordnungswidrigwell, checking for a symbol or var might not be your job as a router.
15:15justin_smithordnungswidrig: the api explicitly says if you supply a symbol, it resolves that symbol at runtime
15:15ordnungswidrigwhich api?
15:15justin_smiththis is so that a routing table can be expressed as edn
15:15justin_smiththe api of the lib I am currently fixing
15:15ordnungswidrigI see.
15:16ordnungswidrig:-)
15:16ordnungswidrigI would then define a multimethod for the types that does the right thing for a) a symbol b) a var c) anything else (e.g. a function)
15:17justin_smithyeah, right now its a cond statement deciding what to store when building the routing table. I was hoping for something more general and elegant than adding more special cases, but that seems to be the path forward.
15:17ordnungswidrigor check with `fn?` which evaluates to true for functions, protocol functions and multimethods
15:18justin_smith,(fn? print-method)
15:18clojurebotfalse
15:18justin_smithnope
15:18ordnungswidrighm
15:18ordnungswidrigmabye just protocols
15:18justin_smiththat's exactly what I was using for the test before ?
15:18ordnungswidrigok, I still don
15:19ordnungswidrig't get the usecase. If it's defined in EDN you cannot have a function there, just symbols, right?
15:19justin_smithwhich is why I came up with this whole "test for AFn" thing, but if as stuartsierra says AFn is not meant to convey anything useful, than I'll just add some clauses to the cond statement or maybe make it a multimethod
15:19justin_smithordnungswidrig: you *can* supply edn
15:19ordnungswidrigI see.
15:19djamesFor run, I'm building up a REPL-based Clojure game
15:19justin_smithyou can also supply a data structure containing things like functions or vars as handler
15:19djameserr. for fun! (and to run) haha
15:20ordnungswidrigjustin_smith: I'd go with a multimethod
15:20justin_smithyeah, then the user can extend the multimethod for their magic thing that should also route
15:20justin_smithgood advice, thanks
15:20djamesI'm thinking about quick ways to make it multiplayer
15:20justin_smith(inc ordnungswidrig)
15:20djamesif each player has a REPL, they could use nrepl to connect
15:20ordnungswidrigdjames: what kind of game?
15:21justin_smithamalloy: can you restart lazybot? I don't think I have the privs
15:21stuartsierrajustin_smith: It will probably be easiest to test for the specific types you're looking for rather than search for some predicate which perfectly separates them.
15:21justin_smithstuartsierra: you're right, thanks. I think I'll use a multimethod, which means user's can extend it.
15:21justin_smith*users
15:22djamesordnungswidrig: well, it happens to be about voting and elections, but that doesn't matter too much
15:22djameshaving a REPL could allow people to cheat by looking too much into the game state atom, but I'm ok with that to start
15:22ordnungswidrigI was more asking is it round based or "live"
15:23ordnungswidrigor realtime
15:23djamesit would be a fun way to introduce friends to clojure as well
15:23justin_smithdjames: you could use an IPC queue for game events
15:23djamesround-based but some actions could be concurrent -- no need to wait for others, for example, to "run polls" or "create an ad"
15:23justin_smiths/ipc/message
15:24justin_smithie. rabbitmq or hornetq
15:25djamesjustin_smith: possibly. i'm starting simpler... here's what I'm wondering about. if each player connects to a shared REPL, they could hack it
15:25ordnungswidrigdjames: mabye this will help http://blog.xebia.com/2014/08/25/vert-x-with-core-async-handling-asynchronous-workflows/
15:25djameswhich is ok to start I suppose
15:26djamesI think what I want is a way for each player to have their own REPL
15:26djamesthen I could write some simple nrepl code to pull the game state from a shared REPL
15:27djamesof course a browser interface would be better once the gameplay is figured out. the game isn't really designed yet
15:32justin_smithdjames: yeah, you could use a web server or a raw socket to send the messages between the repls, but beyond a fairly a small scale, a proper inter-process message queue is actually the simpler solution, compared to hacking your own whatever state-sharing solution
15:33EvanRstate sharing across the network?
15:33justin_smithEvanR: beats having everyone use the same repl I guess
15:34djamesjustin_smith: interesting poitn
15:34justin_smithEvanR: multi-player games do require shared state
15:34EvanRi object to such a concept
15:34djamesI wonder what setup the bot competitions use... probably a central server with shared state and some private information
15:34djamesbots only get the information that they would need
15:34justin_smithEvanR: I look forward to your new, revolutionary, stateless game concept
15:35EvanRin realtime action multiplayer games, you dont synchronize your *separate* states because it would be too slow
15:35EvanRif you did synchronize, its still not sharing
15:35djamesjustin_smith: exactly. I don't play chess a move at a time, I create an immutable value that holds the entire game
15:35justin_smithbut they aren't playing the game if there isn't shared state
15:35EvanRthats not true
15:35EvanRunless this is specifically chess
15:36djamesi was joking
15:36djames(Some people view time as an illusion)
15:36djamesanyhow, this seems like a silly misunderstanding standing in for a proper debate
15:36EvanRbecause of internet latency, there is a necessary idea of approximately equal distinct states, players usually do not care if things are slightly off
15:37djamesif we all explained what we were actually saying, I don't think there would be much disagreement
15:37djamesthanks for the ideas
15:37EvanRin any case, i was wonder how you were sharing states across the network in the sense of clojure sharing data structures among distinct values
15:38djamesmy purpose is to start very simple because I haven't designed, much less play-tested a turn-based strategy game
15:38djamesthe simplest is one REPL
15:38justin_smithEvanR: I think you are using a much more specific and concrete definition of "shared state" than I was. I didn't mean that it was synchronized and identical to all clients, just that there is some method of agreeing eventually on the events that have occured in a shared domain.
15:39djamesif/when the single-REPL approach does not cut it, I'm thinking about going to one master REPL with various client REPLs connected via nrepl
15:40justin_smithdjames: I guess if you trust all the players with full access to the server
15:40djamesat this point, yes. prototyping. e.g. what rules make for fun games, reasonable length, etc.
15:41EvanRwhats the benefit of the repl, a ready-made command line?
15:41justin_smithin that case, you could have all the clients use the same nrepl server, and call that good - only one nrepl server process need exist
15:41djamesyep!
15:42Glenjaminyou might be able to implement any future protections as nrepl middleware anyway
15:43EvanRseems like real protection would be kind of hard to accomplish
15:43EvanRhalting problem?
15:43justin_smithEvanR: Glenjamin: it could use clojail like lazybot does
15:43Glenjaminwell, you can just whitelist, rather than blacklist
15:44xemdetiaEvanR, maybe you should look at this article for ideas http://www.gamasutra.com/view/feature/131503/1500_archers_on_a_288_network_.php
15:44EvanRhow do you blacklist an infinite loop
15:44Glenjaminthread + timeout
15:44justin_smithEvanR: ##(loop [] (recur))
15:44arrdemProof of nontermination? anyone?
15:44Glenjamin,(reduce + (range))
15:44clojureboteval service is offline
15:44Glenjamindno't need proof for a game, just an execution cap :)
15:45justin_smithoops, the above was supposed to call lazybot, who is out
15:45Glenjamin,(reduce + (range))
15:45EvanRxemdetia: yeah i read that a long time ago, its awesome
15:45arrdemjustin_smith: lazybot is down? I thought you fixed him!
15:45clojureboteval service is offline
15:45EvanRway before quake3
15:45arrdem,1
15:45clojureboteval service is offline
15:45Glenjaminhrm, i'm sure that should timeout rather than eval service offline
15:45justin_smitharrdem: hey, the uptime was great
15:45EvanRjustin_smith: surely thats not literally enough
15:45justin_smitharrdem: but clearly not 100% fixed yet
15:46arrdemhum maybe clojurebot is actually having heartburn too
15:46djamesxemdetia thanks for sharing that: this part is interesting "The PCs would basically synchronize their game watches in best war-movie tradition, allow players to issue commands, and then execute in exactly the same way at the same time and have identical games."
15:46GlenjaminEvanR: the main issue is protecting from sideeffects, computation can be limited relatively easily with threads
15:46xemdetiadjames, I thought so too. I thought it would be helpful in EvanR's case because it sounds like he is trying to do the same thing with having synchronized distributed state.
15:47justin_smithxemdetia: djames is the one trying to do that actually, EvanR just has opinions about how to do it
15:47xemdetiasorry I didn't parse far enough back :(
15:47djamesxemdetia: that was written in 2001 before "big data" and "distributed systems" were invented *smirk*
15:48justin_smithxemdetia: happens to the best of us
15:48djamesEvanR: good luck with your game! haha
15:48xemdetiadjames, 'distributed systems' was definitely a term for a long time if you are from mainframeland
15:49EvanRstarcrafts infamous "synchronization failed"
15:49EvanRbecause one player had a slow internet
15:49EvanRnone of this matters because djames is doing a turn-based game
15:51djamesEvanR: not too mention that I am not stuck with a 28.8 modem either
15:51xemdetiadepending on the type of turn based game you could still have a lot of the same problems
15:51EvanR28.8 could have great latency!
15:51xemdetiaunless it is completely isolated turn-taking
15:51djamessome turn-based games allow for interesting game play by resolving async orders in lockstep
15:51EvanRduke3d played great, until someone picked up your phone
15:51justin_smithxemdetia: hell, I have the same problem with board games when we are playing in person and one person just takes way too long making a move and doesn't even realize it was their turn
15:52aaelonyI think the docstring for pmap should contain a note to use shutdown-agents when done. I always forget that.. There is a note in the examples section, but the doc string I think would be preferable.
15:52djamesDiplomacy has a set of rules for combining (and deconflicting if needed) "asynchronous" player actions.
15:52justin_smithgit merge: the game
15:52xemdetiajustin_smith, true enough. I haven't played a board game in quite a while so I forget
15:53EvanRin civilization (some number less than latest) you could not do shit if it wasnt your turn, nice and simple!
15:53djamesthis has been fun, thanks for the articles and ideas
15:53xemdetiaa turned based game just has a poorly specified tick timer :)
15:54djamesjustin_smith: git branch: the game where you never lose
15:54djamesnot sure what turn to make? just branch the game and see what happens
15:54Glenjaminhaving a defined tick means it doesn't have to be a typing contest
15:55Glenjaminsee also: emulator snapshotting
15:55justin_smithGlenjamin: even muds had defined ticks (but you still get typing contests / trigger contests because the ticks were short)
15:58EvanRminecrafts "ticks" are so annoying
15:58EvanRevery tick, do like 100 probabilistic effects to every block in view
15:58EvanRlike 100 times a second
15:58arrdemwhat kind of game are we chatting about? real turn based or pseudo-real time?
15:59xemdetiaI think it is more the concept of synchronization of player moves
15:59arrdemisn't this the minimum diff problem which is NP hard?
16:00pepijndevosIs there something like into-with?
16:00ordnungswidrigpepijndevos: into-with?
16:01pepijndevosI want to turn a seq with duplicated into a map, merging the duplicates.
16:01pepijndevosLike merge-with but for a seq of pairs.
16:01EvanRthats a reduce right
16:02pepijndevosuuuhm... it could be a reduce, yes.
16:02justin_smithyeah, probably easiest to do in a reduce
16:02justin_smith(inc reduce)
16:02justin_smith:(
16:02arrdeminto is just reduce with some magic to use transients
16:03justin_smitharrdem: plus a pretty specific and limited reduction function
16:03arrdemyarp
16:08EvanRis there a form that lets me locally use a different namespace
16:09amalloy(inc reduce)
16:09lazybot⇒ 1
16:09justin_smithamalloy: thanks
16:09justin_smith(inc reduce)
16:09lazybot⇒ 2
16:09justin_smith(inc ordnungswidrig)
16:09lazybot⇒ 2
16:10amalloypepijndevos: it sounds like merge-with
16:10Glenjamin,(merge-with merge [[:a 1] [:b 2]])
16:10amalloy(apply merge-with into {} (for ...)) is a useful pattern
16:10clojurebot[[:a 1] [:b 2]]
16:10Glenjamin,(merge-with merge (hash-map [:a 1] [:b 2]))
16:10clojurebot{[:a 1] [:b 2]}
16:11pepijndevosamalloy, it does, but that really only works on maps
16:11Glenjaminmeh, for is better
16:11amalloypepijndevos: that's what the (for ...) is about. convert your inputs into the map shape you want
16:11Glenjamin$source merge-with
16:11lazybotmerge-with is http://is.gd/eoJ3Mo
16:11justin_smithpepijndevos: well, if you want things merged the way maps would be, doesn't making maps out ofthem make sense?
16:12pepijndevos,(merge-with + {} [[1 2] [1 2]])
16:12clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry>
16:12amalloy,(apply merge-with into {} (for [x '(a b c) y '(1 2 3)] {x [y]}))
16:12clojurebot{c [1 2 3], b [1 2 3], a [1 2 3]}
16:12amalloy,(apply merge-with + {} (for [x '(a b c) y '(1 2 3)] {x y}))
16:12clojurebot{c 6, b 6, a 6}
16:12pepijndevosthe expected result would be {1 4) for my example.
16:13pepijndevosah... interesting
16:15EvanRwith-ns seems deprecated
16:16Bronsa,with-ns
16:16clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: with-ns in this context, compiling:(NO_SOURCE_PATH:0:0)>
16:16arrdemnot even in 1.4...
16:16arrdemwhere even are you seeing that?
16:16justin_smith&(apply merge-with + {} (for [[k v] [[1 2] [1 2]]] {k v}))
16:16lazybot⇒ {1 4}
16:16EvanRgoogle clojure with-ns
16:17Bronsaah clojure-contrib
16:17justin_smith^^ pepijndevos I think that's what you are looking for?
16:17arrdemlol @ contrib
16:17pepijndevosyea
16:19ordnungswidrig&(reduce (fn [m [k v]] (update-in m [k] (fnil + 0) v)) [[1 2] [1 2]]))
16:19lazybot⇒ [1 4]
16:20ordnungswidrigIs there a reducing function which uses multiple cores for a associative reducer function?
16:20ordnungswidrigmaybe using divide and conquer?
16:20EvanRfold
16:20justin_smithordnungswidrig: checkout out core.reducers
16:21justin_smithhttp://clojure.org/reducers
16:21ordnungswidrig*doh*
16:21EvanRyou should definitely profile to make sure doing this actually helps
16:22thearthurDoes The reduce function does this on vectors out of the box
16:22justin_smithEvanR: good point. The fact that the default partitioning is 512 elements is illustrative I think
16:22justin_smiththearthur: no
16:22justin_smiththearthur: regular reduce does not create any new threads or use a thread pool, it does everything in the same thread where it is called
16:23justin_smithunless you pass in a reducing function that uses threads of course...
16:25ordnungswidrig&(r/fold (partial merge-with +) (r/map (partial apply hash-map) [[1 2] [1 2]]))
16:25lazybotjava.lang.RuntimeException: No such namespace: r
16:25ordnungswidrig(clojure.core.reducers/fold (partial merge-with +) (clojure.core.reducers/map (partial apply hash-map) [[1 2] [1 2]]))
16:25justin_smithordnungswidrig: the bots don't let you make / use threads anyway
16:25ordnungswidrig&(clojure.core.reducers/fold (partial merge-with +) (clojure.core.reducers/map (partial apply hash-map) [[1 2] [1 2]]))
16:25lazybotjava.lang.ClassNotFoundException: clojure.core.reducers
16:26justin_smithyou would need to require the ns
16:26Bronsa,(require 'clojure.core.reducers)
16:26clojurebot#<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath.>
16:26EvanR,(boolean true)
16:26clojurebottrue
16:26EvanR,(boolean false)
16:26clojurebotfalse
16:26EvanRis there a boolean? function
16:27BronsaEvanR: no
16:27justin_smith(defn boolean? [x] (contains? #{true false} x))
16:27Bronsa,(def boolean? (some-fn true? false?))
16:27clojurebot#'sandbox/boolean?
16:27justin_smithor that
16:28arrdemwould be entertained to see a benchmark shootout between those and the obvious (or) implementation
16:28ordnungswidriga macro please!
16:28Bronsaarrdem: some-fn is equivalent to the or impl
16:28arrdemBronsa: initially? I totally buy that it'll be equivalent once the JIT has a good look at it.
16:29Bronsaarrdem: it's unrolled
16:29justin_smith$source some-fn
16:29lazybotsome-fn is http://is.gd/iPgf2J
16:29Bronsaarrdem: for the 1-arity, the impl is (or (f x) (g x))
16:29justin_smithyeah, very aggressively unrolled
16:29arrdemBronsa: gotcha.
16:30arrdemBronsa: so remember that logic database thing I was playing with for ASTs?
16:30Bronsayeah
16:30arrdemBronsa: turns out that core.logic has a better one built in
16:30Bronsago figure :P
16:30arrdemgonna try and rebuild Oxcart atop that over Christmas. Should be fun :D
16:30arrdemshould also make stuff like partial application and inlining trivial.
16:31Bronsaarrdem: nice. I've always been a bit worried about core.logic's performance for it to be useful for usage with t.a
16:32arrdemBronsa: yeah not gonna lie I'm concerned that this is gonna blow up in my face, but it'll be a fun experiment and it's easy to backport to my fully transient equivalent (the cutaway crap) if core.logic proves too slow.
17:25puredangerwhy not (defn boolean? [b] (instance? Boolean b))
17:27amalloypuredanger: that is probably a better definition
17:27arrdemoh good java.lang.Boolean is final I was worried for a minute there.
17:27justin_smith,((some-fn false? true?) (Boolean. nil)) ;; puredanger amalloy
17:27clojurebotfalse
17:28hiredmanwell, (def boolean? (some-fn true? false?)) is cross platform
17:28justin_smith,(Boolean. nil)
17:28clojurebotfalse
17:28hiredman(maybe?)
17:28EvanRyurg?
17:28arrdemhiredman: ideally
17:28EvanRis "boolean" even a standard type?
17:28amalloyjustin_smith: well, if you use the Boolean constructor you deserve what you get
17:29puredangerexactly
17:29EvanR,(type true)
17:29clojurebotjava.lang.Boolean
17:29puredangerit's only purpose is to create Clojure wat examples :)
17:29justin_smithamalloy: just showing that some things that are Boolean are not one of the booleans we care about
17:29amalloypuredanger: it messes up plenty of other stuff
17:30amalloylike i remember discovering that when you write Boolean/FALSE to an ObjectOutputStream and read it back in, what you get out is (Boolean. false)
17:30puredangeryeah, deserialization is one place where you can run into this
17:31puredangeralthough in actual Java serialization I assume Boolean objects do the proper readResolve to give you the canonical version
17:31EvanRoO
17:31EvanRall i need is a dynamic check for "booleanness" ;_;
17:32puredangerI think (defn boolean? [b] (instance? Boolean b)) is the best impl
17:32EvanRthats predicated on the java backend right
17:33EvanRjust making sure
17:33puredangeryes
17:33puredangerthere's a ticket out there in jira to create more of these type predicates (which could be made portable by the platform)
17:34amalloypuredanger: no, in actual java serialization they don't; that's what i was complaining about
17:34puredangerthat surprises me
17:34EvanR,(contains? #{true false} nil)
17:34clojurebotfalse
17:34puredangerhttp://dev.clojure.org/jira/browse/CLJ-1298 is the predicate ticket I referred to
17:34puredangeralthough it doesn't actually have boolean?
17:36EvanR,(str (type nil) " is not a valid option, buster")
17:36clojurebot" is not a valid option, buster"
17:36EvanRuhg
17:36justin_smith,(pr-str nil)
17:36clojurebot"nil"
17:36arrdemI have Bronsa's some-fn and puredanger's instance getting to the ns times in a trivial attempt to benchmark
17:36amalloy,(let [a (java.io.ByteArrayOutputStream.) _ (.writeObject (java.io.ObjectOutputStream. a) false) x (.readObject (java.io.ObjectInputStream. (java.io.ByteArrayInputStream. (.toByteArray a))))] (map #(System/identityHashCode %) [x false]))
17:36clojurebot#<CompilerException java.lang.ExceptionInInitializerError, compiling:(NO_SOURCE_PATH:0:0)>
17:37dbascha groups of Booleans are restoring the home of George Boole
17:37amalloypuredanger: well, in a real repl that prints two different numbers
17:37puredangerI believe you :)
17:37EvanRjustin_smith: that is awesome
17:37puredangereverything about serialization is wrong
17:37amalloyi was double-checking for myself; last time i tried it was like four years ago
17:37Bronsa,clojure.lang.IAtom
17:37clojurebotclojure.lang.IAtom
17:38Bronsanice, didn't realize that one got commited already
17:38hiredman:/
17:38puredangerearly alpha
17:38justin_smithdidn't Goetz mention something about a bunch of things about serialization being messed up for backward compatibility reasons because they released a half-backed impl too soon?
17:38puredangeryes
17:39puredangerthere are some internal java paths that let you do object construction without calling the constructor buried in the serialization guts
17:39hiredmanget ready for the land slide of things without atomic semantics that implement IAtom
17:39puredangeryou can use those for great evil
17:40EvanRcan i do "list interpolation" '(x y $z w) :3
17:40KnightsWhoSayNi`(x y ,z w) ?
17:41stuartsierra,(let [stuff [3 4 5]] `(1 2 ~@stuff 6 7))
17:41clojurebot(1 2 3 4 5 ...)
17:41TEttingeroh yeah, that thing
17:45EvanRso with ` i get a lot of my symbols (when i print them out of the repl) now qualified fully
17:45puredangersyntax quote will do that
17:46EvanRwhy does it do that, is there a way to disable that
17:47justin_smithEvanR: for making macros less buggy
17:48puredangersome of the things in tools.macro might be better suited for template-like use cases https://github.com/clojure/tools.macro
17:48justin_smithand you can use `(~'x) but that's kind of ugly
17:48EvanRso a symbol has some understood namespace, is there such a thing as a "free" symbol
17:48justin_smithEvanR: ` is generating namespaces symbols out of unnamespaced ones
17:49justin_smitha normal symbol doesn't usually have a namespace
17:49noonian,'foo
17:49clojurebotfoo
17:49justin_smith,(.getNs 'foo)
17:49clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: getNs for class clojure.lang.Symbol>
17:49justin_smitherr
17:49amalloyEvanR: free symbols cause a lot of problems when used in macros, and ` is mostly used in macros, so its default behavior is to not emit any such symbols
17:49justin_smith,(map namespace 'foo 'bar/foo 'baz/foo)
17:49clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>
17:50justin_smith,(map namespace ['foo 'bar/foo 'baz/foo])
17:50clojurebot(nil "bar" "baz")
17:51justin_smith,(.getNamespace 'foo) ; that's what I was trying initially
17:51clojurebotnil
17:51EvanRwell, ill use (list ... 'symbol ....)
17:52amalloyEvanR: what is an example of an actual list you are building here?
17:53EvanRthere is some code (list {field t} '=> t) which becomes ({:shit t1} => t1)
17:54amalloywell, that seems like a reasonable way to write it. i'm curious what you need that => for at all, though?
17:55EvanRwell something else is going to look for that in the second position to differentiate it from something else, hypothetically
17:56EvanRalso when they get nested, its going to be easier to read and write than if they were just omitted
17:57amalloyEvanR: that sounds like a terrible data structure though, right? like, instead of lists where the second symbol means something different, why not a map like {:differentiator '=> :condition {{field t} t}}
17:57noonianlooks like its a macro for writing midje tests possibly
17:59EvanRamalloy: right, well my way of doing what youre doing is [discrimcode a b c ...] and then core.match
17:59EvanRbut right now im not doing that
17:59EvanRwhat i said earlier is hypothetical at best
18:04EvanRwhats an idiomatic way to have a counter, incremented in place. an atom with a number in it?
18:05mdrogalisEvanR: Yeah.
18:06benzapso I have a basic situation that I know should work, but doesn't
18:07benzap,(defn foo [x & {:keys [bar] :or {bar "ha"}}] (println x bar))
18:07clojurebot#'sandbox/foo
18:08benzap,(foo 1 :bar "test")
18:08clojurebot1 test\n
18:08benzap,(defn bar [x & args] (apply foo x args))
18:08clojurebot#'sandbox/bar
18:09benzap(bar x :bar "test")
18:09benzap,(bar x :bar "test")
18:09clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0:0)>
18:09benzap,(bar 1 :bar "test")
18:09clojurebot1 test\n
18:09benzap...
18:09amalloyyeah, that works fine. you have some other problem
18:11benzap,(defn bar [x & {:keys [bar] :or {bar "haha"} :as args}] (apply foo x args))
18:11clojurebot#'sandbox/bar
18:11benzap,(bar 1 :bar "test")
18:11clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: [:bar "test"]>
18:11amalloybenzap: mhm. because args is a map there, not a seq
18:11benzapah
18:11benzapdo I need to convert it to a seq?
18:12amalloybenzap: i mean, there are things you can do to make this work
18:12amalloybut by far the easiest is to use {:keys ...} instead of & {:keys ...}
18:12amalloylook at all this trouble the varargs are causing you, and the only advantage is that you save the two {} characters when calling the function
18:12benzapyeah true, but it looks pretty
18:13EvanRmake love not varargs
18:13justin_smithbenzap: use of vararg keys is also harder to compose - it's nice to be able to just pass the map along
18:14alexyakushevbenzap: vararg key-value arguments are usually used in user-facing functions
18:15amalloyalexyakushev: even in user-facing functions they're not great
18:16alexyakushevamalloy: Maybe. But my argument was that they are definitely not great deeper in the callstack
18:16benzapyeah, I converted it away from varargs, and I don't have any troubles now
18:17alexyakushevHm, good to see this point is now updated here http://dev.clojure.org/display/community/Library+Coding+Standards
18:17alexyakushevI remember it used to promote unrolling kw arguments
18:17amalloybenzap: it's way easier to deal with stuff when there's an actual object, with a name, representing it; varargs are like "a bunch of disconnected things" all with no name. that's fine sometimes, eg for the args to +, but for option maps, where you might want to do anything at all other than destructure them once, having a value representing it makes stuff easier
18:18arrdemalexyakushev: someone is gonna figure out that I fixed it eventually :P shhhhh
18:18amalloyoh, that's nice, alexyakushev
18:19alexyakushevarrdem: you better hurry spreading the word before I steal all the credit
18:20arrdemalexyakushev: as long as the change doesn't get rolled back I could care less.
18:22alexyakushevarrdem: you mean you couldn't care less :p
18:23arrdemthat
18:48cfleminghellofunk: Yes, that all works equivalently for clj and cljs
18:59EvanRwhat does it mean when i get this error, and the backtrace has nothing within any of my source code
18:59EvanRArityException Wrong number of args (1) passed to: type-checker$what-is-type-in$fn--14540$fn clojure.lang.AFn.throwArity (AFn.java:437)
19:00EvanRim using the right number of arguments everywhere
19:00EvanRmaybe i need to reload the repl
19:01EvanRdid not help
19:01EvanRbacktrace just says stuff like lazy seq, clojure core
19:01amalloyEvanR: print the whole stacktrace, paste it to refheap or something
19:02EvanRim trying to do a into {} map on a map
19:02amalloyif it says nothing meaningful to *you*, that doesn't mean there's nothing meaningful in it
19:03EvanRhttps://www.refheap.com/dd171e33c648f6a446818dfe8
19:05EvanRit does have three lines from my source code in there
19:05amalloyokay, so the sequence you are trying to dump into a map is lazy, and realizing it causes an exception
19:05EvanRcripes
19:05amalloyie, you have written (into {} (map f xs)), and takes too many args
19:05amalloyer
19:05amalloyf takes more than one arg
19:06EvanRok, its (fn [k v] ...) but i think it needs to be (fn [[k v]] ...)
19:06amalloyaccording to the exception message you pasted earlier, that f is what-is-type-in
19:06EvanRwell thats not right, may thats just what function the function is in
19:06justin_smithyeah [[k v]] is what you want for mapping over a hash-map
19:07EvanRlovely
19:07amalloyjustin_smith: yes, although (for [[k v] m] ...) is almost always clearer than (map (fn [[k v]] ...) m)
19:07amalloyit also has the advantage that this sort of mistake is immediately apparent
19:07amalloybecause (for [k v m] ...) will immediately fail to compile
19:08EvanRi used for [[k v] m] [k ...] instead
19:08EvanRand it worked
19:08EvanRand thats more clear?
19:08hyPiRion,(fn [m] (for [k v m] [k v]))
19:08clojurebot#<sandbox$eval25$fn__26 sandbox$eval25$fn__26@e28d65>
19:09amalloyhyPiRion: har har, where is the u+FEFF?
19:10EvanRwell i wrote a map values function, and i cant be arsed to import the dang module its in ...
19:10EvanRi wish it was just built in
19:10hyPiRionbetween the k and the v – I'm a bit surprised I haven't removed this "handy" keyboard shortcut already. I accidentally use it pretty often
19:11EvanRF11F FE1F F00F FEff
19:11EvanRi smell the blood of an englishmen
19:22dbaschthe link to alpha4 remains broken, in case someone cares http://clojure.org/downloads
19:22amalloyhah, that url
19:23amalloy.../1.7.0-alpha3/clojure-1.7.0-alpha4.zip
19:23dbaschthe script to generate that page is also alpha
19:23amalloydbasch: it's a challenge: if you can't figure out how to fix the url, you don't deserve to download the latest alpha
19:24dbaschbut if you know how to fix the url you’re probably using leiningen anyway
19:46devnoff topic: pretty cool visualization of an ongoing DDoS http://map.ipviking.com/
19:53profilHey guys, which is faster, running rest on a set or running disj? How can I find this information?
19:54nooniandevn: that is mesmerizing to watch
19:55hiredmanprofil: disj will return a set, rest will not
19:56profilhiredman: alright, and I guess disj is faster than running (set (rest set))?
19:58hiredmanwell rest returns a seq, which has O(n) membership testing, and sets have something like O(log_32n) for membership, given a structure with O(n) membership testing, how effeciently could you turn it in to something with O(log_32 n) membership testing?
20:00profilO(n log_32 n)?
20:02justin_smithdevn: hah, lots of people targeting st. louis right now
20:04dbaschprofil: why would you want to call rest on a set anyway? do you want to remove a random element?
20:04nooniani'm trying to figure out what is the island between africa, south america, and antarctica thats labeled Mil/Gov
20:05profildbasch: no, the first element?
20:05dbaschprofil: sets have no order
20:05justin_smithprofil: the "first element" of a set is not defined
20:05profildbasch: yeah I understood that now..
20:06justin_smithit's an implementation detail
20:06profilits too late.. I'm tired :D
20:06hyPiRionIt is in an ordered set
20:06profilbut its okay to use first on a set right?
20:07justin_smithhyPiRion: oh?
20:07hyPiRionjustin_smith: ##(first (sorted-set 3 4 1)) always returns 1
20:07lazybot⇒ 1
20:08justin_smithhyPiRion: wait, I misparsed the "it" to refer to profil's set, I know ordered sets exist :)
20:08sskhow complete is apache spark clojure binding
20:08justin_smith profil: sure, but who knows which item you'll get ##(first #{:a :b :c :d :e :f :g :h})
20:08lazybot⇒ :e
20:08dbaschprofil: “okay” depends on what you want
20:09profiljustin_smith, dbasch: I dont really care, I just want any item
20:09hyPiRionthen first is okay
20:09profilI am porting a flood fill algorithm from javascript to clojure :)
20:09profilusing sets for cells which has been visited, and which should be visited
20:09justin_smiththere is also ##(rand-nth #{:a :b :c :d :e :f :g :h}) if you care in that you want it to be random and not just implementation defined
20:09lazybotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentHashSet
20:10justin_smith:(
20:10dbasch&(first (set [5 6 7 8]))
20:10lazybot⇒ 7
20:14dbaschnoonian: Bouvet Island
20:14noonianthats what i thought
20:14profilI have a vector which contains vectors, is there a nicer way to get a value from that than using "(nth (nth vec x) y)"?
20:14noonianall info says its uninhabited
20:14dbaschnoonian: it has a tld, .bv
20:15justin_smith,(([[:a :b :c] [:d :e :f]] 1) 2) ; profil
20:15clojurebot:f
20:15justin_smith,(get-in [[:a :b :c] [:d :e :f]] [1 2]) ; profil
20:15clojurebot:f
20:16profiljustin_smith: ah nice, get-in would be best, thanks :)
20:16justin_smithstrictly requires vecs, will break with lazy-seq or list
20:17profilyeah, I am using vectors. Parsing json arrays turns into vectors :)
20:18justin_smithget-in has the bonus that it also works with hash-maps enclosing / nested with vectors
20:19profila
20:19profiloh nice, thanks for your help :)
20:19justin_smith,(get-in {:a [1 2 3]} [:a 1])
20:19clojurebot2
20:20profil,(get-in {"layout" [[1 2] [3 4]]} ["layout" 1 1])
20:20clojurebot4
20:20profilyey :)
20:31ssk(eval '(+ 2 3 5))
20:40josiah14what's the advantage of using defn over declare if declare ensures that my function will be available no matter when/where in the program I call it?
20:40justin_smithjosiah14: all declare does is create a var, it doesn't give it any value
20:41josiah14ah, understood
20:41justin_smithyou eventually need to use def, or defn, or intern, or ... something to assign that value
20:41josiah14so I would have to use defn and declare together for functions
20:41josiah14that makes sense.
20:42justin_smith,(declare f)
20:42clojurebot#'sandbox/f
20:42justin_smith,f
20:42clojurebot#<Unbound Unbound: #'sandbox/f>
20:42josiah14I'm feeling that Clojure is going to be fairly easy to pick up for me given I already know Haskell
20:43josiah14I wasn't sure how much my knowledge would xfer, but knowing Java already, and knowing Haskell, it feels sort of like, oh, I get it
20:43nullptr`josiah14: very likely true
20:44justin_smithyeah, between Java for the underlying libs / apis, Haskell for the fp concepts, and scheme for the trivial syntax, you're most of the way there
20:44justin_smithwe also get a few idioms and naming conventions from scheme
20:46josiah14ah, gotcha
20:46josiah14yah, I don't know Scheme
20:46justin_smithout of the three, scheme is the simpler one by far
20:47josiah14but my hope is that learning Clojure will get me close enough that i could just pick it up and a week if I wanted to use it for some scripting or something
20:47josiah14yah, I hear people praise Scheme all the time for its simplicity
20:48justin_smithwell, depending on your definition of "scripting", Clojure might not be a great choice. Clojure is best at long-running processes that can use as much RAM as they need to execute tasks efficiently, once minimal resource usage and fast startup time become desirable, Clojure becomes less desirable.
20:49josiah14I still have some learning on Haskell to do, but it's for things like, how the 'F' do I use a hashmap, or efficiently parse strings/text, without the use of state, and learning the crazy monadic implementations they have for solving those problems
20:49justin_smithbut I love using Clojure for long running tasks on dedicated servers, it is awesome for that
20:51josiah14justin_smith: for Scripting I was talking about Scheme. I figured, if I learned enough Clojure to build the sample Twitter app from the Rails tutorial by starting with Ring and building up from there, Scheme should be simple enough to pick up when I want something for a short running process
20:51justin_smithhh
20:51justin_smithyeah, that makes sense
21:36schrottihm can't i use into with swap!?
21:37schrottialways get an arity exception
21:37kenrestivoexample?
21:37schrotti(swap tasks into @tasks [(future (inc 1))])
21:37schrotti(def tasks (atom []))
21:37schrotti+!
21:38puredangerthe @tasks there is implicit and not needed
21:38TEttinger,(let [tasks (atom [])] (swap! tasks into [(future (inc 1))]))
21:38clojurebot#<SecurityException java.lang.SecurityException: no threads please>
21:38TEttingerfuture ban
21:38TEttinger,(let [tasks (atom [])] (swap! tasks into [(inc 1)]))
21:38clojurebot[2]
21:38schrottipuredanger: thanks
21:39puredangerkeep in mind that swap functions may be retried in the case of collision so they typically should not have side effects
21:39TEttingerthe atom syntax is a little tricky at first but quickly gets familiar
21:39schrottithanks for the hints, appreciate it
21:40nikki93is the book "clojure programming" from o'reilly still relevant/up-to-date for the latest version of clojure?
21:41TEttingermostly, yeah, I think that's the one I have. I didn't read the whole thing but it explained atom, var, agent, ref very well
21:42nikki93cool
21:42nikki93and would you guys recommend that vs. "clojure for the brave and true"?
21:42puredangerthey're both good; different styles
21:42nikki93I'm planning to use emacs with cider etc. and have a little bit of lisp experience from land of lisp, and lots of general coding experience
21:43puredangerStu mentioned to me recently that he checks the code examples for every new version of Clojure and he has made 0 code changes from 1.2 through 1.6 for his Clojure book
21:44puredangerin general, we try to make things relatively stable across releases
21:45puredangerwhich means that the Clojure books mostly age by not including new stuff rather than actively being wrong
21:45puredangerif I get off of irc and work on it instead, we will hopefully get our book into beta in a month or so https://pragprog.com/book/vmclojeco/clojure-applied
21:46nullptr`puredanger: looking forward to it!
21:46puredangerI'm looking forward to being done with it!
21:47nullptr`speaking of "new stuff", is there any plan to cover transducers or core.async?
21:47puredangerin our book? definitely.
21:48nullptrthat's great, both i think could benefit from extended coverage
21:48puredangerunfortunately I spend my days making the stuff I wrote the night before out of date
21:48kenrestivo+1 for async. it seems most of the knowledge of it is folklore still.
21:48puredangerwe will not be a canonical or exhaustive resource, but I think it will have more coverage than anything else out there
21:49kenrestivothere's an art form to using it right, i think
21:49puredangerI think a ~100 pg short book only on core.async would be killer
21:49puredangerI'm not going to write it :)
21:49kenrestivoone can quickly get into a kind of async hell with channels everywhere and trying to keep track of all the different kinds of messages that can be sent/received
21:50nullptragreed. you probably know the people who are qualified, talk them into it!
21:50gfrederickscall it One Weird Macro
21:50puredangerI don't think Tim B has any interest. Someone tell Stuart to do it. :)
21:51kenrestivoare there oddities of transducers which need documenting? i watched rich's presentation, and after hearing his analogy to peeling apples, it all made sense
21:51puredangerplenty :)
21:51nullptrgfredericks: ha!
21:51puredangermaking new ones all the time :)
21:52kenrestivoi haven't used them in production yet. waiting for 1.7
21:52nullptryeah, i think weird eager/lazy implications could consume quite a few pages
21:52puredangersome of the benchmarking I've done is really promising - I think when used pervasively, they are going to be really important for some applications
21:53puredangerfor example, you can see a bit of it at http://dev.clojure.org/jira/browse/CLJ-1546 where I've been reworking vec
21:55puredangerthere's a chart attached with a lot of timings. vec on PersistentList (which goes via IReduce paths instead of seq paths) is ~7 secs for 1024 element list vs 28 sec for into.
21:55puredangerthat's not even transducers but what can sit at the bottom
21:55puredangerwhen the vec stuff there is combined with the Iterable improvements on http://dev.clojure.org/jira/browse/CLJ-1499, I see similarly big improvements on maps and sets
21:56puredangerand I have a few scratch times for a few new transducers in http://dev.clojure.org/jira/browse/CLJ-1601 (adding distinct, interpose, and map-indexed transducers)
21:57puredangerex: distinct with seq - 821 micro sec vs 43 micro sec for transducer version
21:57nullptrwow, juicy stuff
21:57puredangerall of those are effectively done and waiting for inclusion still
21:58puredangerwhen you start to combine these so you can get a single very fast pass instead of many layers of sequence functions, it adds up
22:00puredangerstill in work are new reducible versions of range, cycle, iterate, keys, vals
22:00nullptryes, and given the typical data oriented nature of clojure code this isn't theoretical -- good stuff indeed
22:01puredangerI'm finding it pretty easy to put into practice - it does really require you to separate how you think about the algorithm part vs the output part
22:01puredangerthe two functions to transduce that is
22:06TEttingerthis is great stuff, puredanger
22:06TEttingerspeeding up sequential data operations should be a massive boost to idiomatic clojure performance
22:08puredangerwell, unfortunately you don't get it all for free. you do have to explicitly use transducers but I think that's an easy thing to do in many cases.
22:08puredangerwhen we can integrate Zach's unrolled small collections, I think we will see a lot of programs become automatically faster
22:08TEttingerZach being ztellman?
22:09puredangeryeah. while we had the opportunity, I did some code review with him at the conj and I think it should be no problem to get that into 1.8.
22:09TEttingerthat dude is the clojure performance wizard
22:09puredangerthis is http://dev.clojure.org/jira/browse/CLJ-1517 I'm talking about
22:11puredangerin service of the vec enhancements, I did some histograms of programs to see typical sizes of collections being passed around. unsurprisingly, tons of collections < 10 elements.
22:13TEttingeroh yeah, that's what I'd expect too
22:25cflemingpuredanger: I want that change.
22:25puredangerwhich?
22:25cflemingsmall collections
22:25puredangerme too. but it's not going to make it in 1.7.
22:25cflemingI think that's going to be a great addition to Clojure
22:26cflemingYeah, I understand. That's one of those changes I'd consider running a patched version for.
22:26puredangerit has some pretty wide impacts - Zach's done the dev work but not the integration part of it. I know of a few problem areas that will need some attention.
22:27cflemingInteresting, what are the problems there? I talked to him at the conj, I know that he didn't do the integration to instantiate the unrolled collections.
22:27cflemingBut that doesn't seem too problematic.
22:27puredanger80% of it is easy and then there's the other 80%
22:28cflemingHah.
22:28puredangerthere's an existing issue with how constant collections are represented in bytecode that Nicola and I have both spent a fair amount of time on and Rich has looked at a couple of patches even.
22:29puredangerit mostly comes up right now on PAM/PHM confusion but now we will have not 2 but 8 or 9 or whatever implementations which I think will make it far more obvious
22:29puredangerand extend to vectors
22:30cflemingOk, interesting. Is there a jira issue for that?
22:30puredangerpresumably PAM goes away - that will impact some stuff but I'm not really sure what
22:30puredangeryeah….
22:30cflemingYeah, it'll be interesting to see how much code inadvertently relies on PAM being sorted.
22:31puredangera couple actually
22:31puredangerwell that aspect is retained by Zach's collections
22:31cflemingAh ok.
22:31puredangernot sorted - ordered
22:31cflemingYeah, maintained in insertion order is a better way to put it.
22:31Wild_Catwhat changes are being considered for small collections?
22:31emaczenDoes anyone have experience configuring MongoDB with a Luminus webapp?
22:31puredangersome tickets - http://dev.clojure.org/jira/browse/CLJ-1093
22:32puredangerWild_Cat: see http://dev.clojure.org/jira/browse/CLJ-1517
22:32Wild_Catalso, Guest1882 is spamming in queries. Any ops there?
22:32cflemingWild_Cat: Also see http://blog.factual.com/using-clojure-to-generate-java-to-reimplement-clojure, it's a good read.
22:32puredangeroh yeah, much better pointer :)
22:34puredangersomeone has suggested adding more ops here and I'd be happy to do that but I'm not sure how to make that happen or who exactly current ops are
22:35Wild_Catpuredanger, cfleming: excellent, reading that now. Thanks.
22:35justin_smithpuredanger: I know technomancy has ops
22:35cflemingpuredanger: I'm also dying to use transducers in Cursive, I use sequences all over the place, and I have a ton of use cases for reduce-like things that are a pain to implement using actual reduce (mostly 1-N transforms, or M-N transforms).
22:36cflemingI'm hoping I'll be able to provide a quickfix to auto-convert threaded forms to transducer use.
22:36puredangercfleming: I hope that you can use them soon :)
22:36hiredmantechnomancy is/was the newest op, but he isn't in?
22:36puredangercfleming: in some cases that's obvious but in others I think it really requires rethinking parts of your program
22:37puredangerlike merely replacing sequence transformations with transducers wrapped in a sequence call is probably not what you really want
22:37cflemingpuredanger: Yeah, no doubt. I need to try some manual translations to get an idea of how to do it first - any suggestions for tricky cases welcome.
22:37puredangerbut I haven't really done this kind of refactoring on any scale so maybe there are
22:38cflemingRight, but as long as it produces equivalent working code, it's probably a good start to a refactoring, and should be faster.
22:38cflemingI'd probably mostly want to convert to transduce, which is not exactly equivalent but mostly.
22:38puredangerprobably. it also has different laziness semantics though. in many cases, you won't notice but in some you will
22:39puredangercfleming: transduce is importantly different in separating the transformation from the final reducing function
22:39cflemingYeah, no doubt. Still, since it's a manual change I can assume the user knows what they're doing.
22:40cflemingpuredanger: Yeah, like I say I haven't done any of this manually yet so I'm still not sure what I want. But I'm hopeful that I can provide some automatic translations that will be pretty helpful.
22:40puredangerwhich will automatically use transients if possible
22:41cflemingI'm planning to implement a new duplicated code inspection in v14, so hopefully it'll also be able to automatically suggest extracting common transformations.
22:41puredangercool
22:42cflemingYeah - I'm imagining a series of options for the transfomation - switch to sequence, switch to transduce with into etc.
22:42puredangerthere are definitely some common patterns
22:42cflemingWhen I get a moment I'll try it out and send it to you guys to try out - you've done this a lot more than me.
22:43cflemingThanks for that JIRA pointer BTW, interesting.
22:44puredangerbeing able to switch something like (->> s (filter odd?) (map inc) (reduce +)) into (transduce (comp (filter odd?) (map inc)) + s) would be cool
22:45andyfIs an email to clojure-Dev nominating other ops a way to proceed ?
22:45puredangerI don't even think that's necessary?
22:45puredangerjust whoever can do the thing needs to do the thing
22:46puredanger(I am a pretty dumb irc user so I don't even know how to do whatever I would need to do but I'm sure that's google-able :)
22:46cflemingpuredanger: Right, that should be relatively straightforward, as long as the thread form only contains core seq functions.
22:47cflemingSince the user has to explicitly request the transformation, as long as it doesn't totally break code I think it'll be useful.
22:47justin_smithpuredanger: whoever has ops now has the power to add other users to the list of people who can get ops. The right way to do it is to register them as people who can get ops via chanserv, and then they can ask chanserv for ops priveleges whenever needed.
22:47puredangerthe second half of that says things I don't understand but I am on board :)
22:48justin_smithpuredanger: chanserv is an automated thing - you say "I want my privs" and if you are on the right list it turns those privs on
22:48puredangerthe next time I see technomancy on here I'll ask him about it
22:48puredangerwhere "you" == some registered nick?
22:49kenrestivofor some reason, the discussion of unrolling loops me reminds me of f_unroll_loops and gentoo
22:49justin_smithpuredanger: yeah, "/msg chanserv help" for the basics
22:53puredangerthx
22:53justin_smithI think amalloy would make a good op
22:54puredangerfor sure
22:55amalloylast time this came up, technomancy found out he had some kind of limited ops and couldn't promote anyone else
22:55justin_smithwho does chanserv think is in control?
22:55puredangerah
22:55justin_smithchanserv says rhickey
22:56puredangerhe's on here all the time :)
22:56justin_smithwell, rhickey can just do a quick login and give full ops to technomancy, and then technomancy can do the rest
22:57puredangerdoes that mean that no one has rights? probably chouser too I'd guess.
22:57justin_smithmaybe someone else has those privs - but rhickey definitely does
22:58kenrestivolast @'s i've seen in recent years have been chouser and technomancy
23:04puredangergood times…. http://clojure-log.n01se.net/date/2008-02-01.html
23:05justin_smithnice
23:08puredangerin putting together the data for the conj timeline shirt I went back and read a ton of old #clojure logs and commit logs - so weird to be able to travel back to that time with such high fidelity
23:08puredangerit repeatedly freaked me out to see things get developed in java and c# in parallel too
23:10hiredmannostalgia as a service
23:10schrottihehe
23:27hiredmanmy first interactions with a number of past and present coworkers are preserved in the logs of #clojure
23:35kenrestivo~seen rhickey
23:35clojurebotIt's greek to me.
23:35lasericusWould anyone be so kind as to tell me why this expression ((partial assoc {:text "flarp"} :id) (-> {:foo 45} vals first)) evaluates to {:id 45, :text "flarp"} while this expression (-> {:foo 45} vals first (partial assoc {:text "flarp"} :id)) reduces to a partially-applied function?
23:35justin_smith$seen rhickey
23:35lazybotrhickey was last seen quitting 76 weeks and 1 day ago.
23:35kenrestivo$seen chouser
23:35lazybotchouser was last seen joining on clojure 4 weeks and 4 days ago.
23:35kenrestivo$seen technomanc
23:35lazybotI have never seen technomanc.
23:35kenrestivo$seen technomancy
23:35lazybottechnomancy was last seen talking on #leiningen 4 hours and 47 minutes ago.
23:36kenrestivoalright, there's the relevant metrics
23:38TEttingerlasericus: -> inserts the data that was returned by the previous threaded form as the first argument to the next form. (partial assoc {:text "flarp"} :id)) becomes (partial :foo assoc {:text "flarp"} :id)) there
23:39TEttingerI'm guessing that's the problem
23:39TEttingeryou can defn the fn earlier or use let
23:39lasericusTEttinger: Interesting. Let me riddle what you just typed for a moment.
23:39kenrestivoyou could try the hack of (#(assoc ....))
23:41kenrestivoyeah, the -> is sticking the output of "first" after partial. you could try hacking it to use ->> instead ....
23:41kenrestivoor, when i find myself having to do nasty hacks to make a perfectly OCD -> thread, i give up and just use nested parens instead
23:41justin_smithalso, you can stick ->> inside ->
23:41kenrestivosometimes aspberger's isn't really an advantage.
23:42lasericusI would imagine - now that I'm re-reading the ->> docs - that simply replacing -> with ->> in my above example would have resulted in the desired behavior (given that the result of the form immediately before partial would be used as the last argument to partial).
23:42justin_smith,(-> {:foo 45} vals first (->> (assoc {:text "flarp"} :id)))
23:42clojurebot{:id 45, :text "flarp"}
23:43justin_smith,(->> {:foo 45} vals first (assoc {:text "flarp"} :id)) ; actually
23:43clojurebot{:id 45, :text "flarp"}
23:43justin_smithbut sometimes there is reason to use the prior version
23:43justin_smithyou don't even want partial there
23:44lasericusjustin_smith: Bizarre. It appears to me that the expression (assoc {:text "flarp"} :id) would result in an ArityException.
23:44justin_smithlasericus: macros
23:45justin_smith->> doesn't do anything at runtime, it transforms the input before it is compiled
23:45lasericusjustin_smith: Ah, yes. Thanks for the help.
23:53TEttingerlasericus: aspberger's is awesome for maintaining focus, so are adderall and its family of stimulants. with their powers combined, they form THE ATTENTION SQUAD!
23:54TEttingererr, ^ kenrestivo
23:59kenrestivolazybot: no, assoc needs to know what key to assoc to , and what data to stuff in there. if you just do (assoc feh :meh) there's someting missing