#clojure logs

2015-05-08

01:40edbondquestion about core.memo: is it possible to combine several strategies? For example ttl + lru
01:45dysfunyou mean core.cache?
01:45dysfuncore.memoize uses core.cache under the hood
01:45edbondyes, I use core.memoize. It is higher level lib over cache?
01:46dysfunyou can provide a custom core.cache to core.memoize
01:47edbondok. Another question: is it possible to run cached function in background and return last known result value?
01:47edbondI think this may result in many updates running at the same time. So need to coordinate updates somehow.
01:48dysfuni think you're outgrowing core.memoize and probably want direct cache control
01:49dysfunbut c.m has functions for manipulating the cache too, have a play
01:50dysfunas for your coordination, well, sounds like the perfect job for an atom
01:51edbondyes, I basically need an atom with expiration for keys and update in background. Keep only one updater per key.
01:52dysfunthat sounds like an atom with a core.cache
01:52Niachttp://paste.ubuntu.com/11020908/
01:53dysfunNiac: is that fibonacci?
01:53edbondNiac, recur should be in same order as loop
01:53edbondNiac, take 2 will take first two, not last two
01:54dysfunincidentally, also a fantastic example of a good place to use core.cache :)
01:55edbondc.c should be avail to any function :)
01:55edbond(defn ^{:cache :ttl} ...)
01:55NiacSo,can anybody show me the right code?
01:56dysfunedbond: disagree. tht would encourage a lot of laziness. if you really want it, you can write a macro
01:56edbondNiac, some examples here - http://rosettacode.org/wiki/Fibonacci_sequence#Clojure
01:59dysfuni reckon there's a fairly short version involving 'reduced' waiting to be written
01:59dysfunreductions, even
02:01amalloydysfun: i think the version with reductions is just the iterate solution with an ignored argument thrown in
02:02dysfunquite possibly. i've not been awake long enough to actually write code yet
02:03dysfunand frankly i'm not sure much code is going to be written in the uk today, given we're all mourning our election results
04:34dfletcher,((fn [n] (letfn [(f [n a] (if (= n 2) a #(f (dec n) (conj a (+' (last a) (nth a (- (count a) 2)))))))] (trampoline f n [0 1]))) 10)
04:34clojurebot[0 1 1 2 3 ...]
04:34dfletcher:)
04:34dfletchercouple fun timewasters from a reddit post https://blog.svpino.com/2015/05/07/five-programming-problems-every-software-engineer-should-be-able-to-solve-in-less-than-1-hour
04:35dfletcherclearly written for procedural people hehe sum numbers using for and while heh.
04:36dfletcher(apply + [1, 22, 37, 55]) ; heh
04:43Empperi_dfletcher: damn I fail in those tests. "Write three functions that compute the sum of the numbers in a given list using a for-loop"
04:44Empperi_I don't have a for loop in Clojure :(
04:45edbondthe tasks from pre-FP time
04:45Empperi"Write a function that combines two lists by alternatingly taking elements" - interleave and done
04:46edbondEmpperi, pretend you don't have interleave
04:46dfletcherhuh
04:46TEttinger,(mapcat vec [1 2 3] [10 20 30])
04:46clojurebot#error{:cause "Wrong number of args (2) passed to: core/vec", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (2) passed to: core/vec", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 36] [clojure.core$map$fn__4536 invoke "core.clj" 2627] [clojure.lang.LazySeq sval "LazySeq.java" 4...
04:46dfletcher,(interleave [:a :b :c] [1 2 3])
04:46clojurebot(:a 1 :b 2 :c ...)
04:46TEttinger,(mapcat vector [1 2 3] [10 20 30])
04:46clojurebot(1 10 2 20 3 ...)
04:46dfletcher,(flatten (mapv list [:a, :b, :c] [1, 2, 3]))
04:46clojurebot(:a 1 :b 2 :c ...)
04:47dfletcher^^ that was my solution
04:47TEttinger~flatten
04:47clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
04:47TEttingermainly because yours doesn't work if it's a nested list
04:47dfletcherheh yeah couldn't figure out how to get mapv to stick 2 items into the list heh
04:47TEttingermapcat
04:47dfletcheraha
04:48TEttingeror concat after creating a list of pairs
04:50dfletcher,(doc mapcat)
04:50clojurebot"([f] [f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection. Returns a transducer when no collections are provided"
04:58egasimuswhat's an up-to-date, per-project way for me to have `clojure.tools.namespace.repl.refresh`, `clojure.pprint.pprint`, etc utilities imported when I run `lein repl`?
05:00egasimusis perhaps `:injections` what I'm looking for?
05:45egasimustried :injections as well as https://github.com/zcaudate/vinyasa
05:45egasimusbut running (refresh) clobbers anything I've required
07:09jonhgood mornin #clojure~
07:16zotis there by chance a way to convince cider to jump into java source?
07:32wasamasaurgh
07:34wasamasaI've told #freenode now, let's see what happens
08:24wasamasa...
08:25wasamasawho are the ops in this channel?
08:25powrtoc_zot: not that I know of yet... but I'd be interested too if you find out how :-)
08:29justin_smithwasamasa: amalloy_ and puredanger and technomancy (who never shows up here any more)
08:29wasamasajustin_smith: yeah, I figured I wouldn't get to see technomancy in here ever since his announcement of moving overseas
08:29escherizeSo, I was playing with bocko. What's a good way to make an event loop?
08:30escherizelike, to do an animation
08:31wasamasajust loop and recur with a waiting period and callback function?
08:32oddcullygive clojurebot op and add a vote feature? or are op bots against freenode rules?
08:32mpenetit dangerous, freenode or not
08:33mpenetit's*
08:33wasamasaoddcully: votekicks?
08:33wasamasaoddcully: feels kind of wrong
08:34oddcullywell, then /ignoreance is bliss
08:34escherizewasamasa: lgtm, thanks
08:34wasamasaescherize: that's how I've seen a scheme library do it
08:35wasamasaescherize: it lets you establish the canvas/game properties first (like, dimensions, color, timeout, etc.)
08:35escherizeif i want to keep the repl functioning, should i use a future?
08:35wasamasaescherize: then you start the animation with a callback function that is called with the canvas as argument
08:35justin_smithyou could even use core.async channel ops instead of callbacks
08:35escherizei get the f(state) => new-state
08:36Ricardo-ArgesAnyone familiar with reagent?
08:36justin_smithRicardo-Arges: I use it every day, what's up?
08:37Ricardo-ArgesHey justin_smith. I'm looking through its docs and to try and figure out if there's a way to return a mix of its hiccup-like mark up and raw HTML.
08:37Ricardo-ArgesSay... have a [:ul ] inside of which I insert a list of raw <li>s
08:37justin_smithRicardo-Arges: I haven't used raw html at all
08:38escherizeI use reagent every day too.
08:39justin_smithescherize: cool, I am loving it so far
08:39escherizeme too justin_smith. :)
08:39escherizeI got to meet Mike Thompson last week
08:40escherizehe's a funny thoughtful guy
08:40Ricardo-ArgesHow about that escherize? Something like a :raw or a way to just pass it the inner html. If I just return a string, it'll get wrapped in a span, and if I do [:li the-text] it gets quoted... so any inner HTML is displayed instead of rendered.
08:40escherize(he wrote re-frame)
08:40escherizewhat's a raw <li>, Ricardo-Arges
08:40justin_smithRicardo-Arges: there are functions that return hiccup-ized data structures from html
08:41Ricardo-ArgesI get a series of items from the backend. They may contain embedded HTML.
08:41escherizeoh, so a string like "<li>a</li><li>b</li>"?
08:41justin_smithRicardo-Arges: fix the backend?
08:41escherizehaha
08:41Ricardo-Argesjustin_smith: Heh, it's parsed data.
08:42Ricardo-Arges*scraped
08:42justin_smithRicardo-Arges: there's a scraper in enlive that will turn it into hiccup format
08:42justin_smitherr wait - maybe not the one in enlive
08:42justin_smithbut I know this exists
08:42escherizehttp://stackoverflow.com/questions/11094837/is-there-a-parser-for-html-to-hiccup-structures
08:42escherizethis^ ?
08:43Ricardo-ArgesOh, that'll help. I'll give it a shot, thanks!
08:44escherizebut yes, justin_smith, have you checked out re-frame?
08:44justin_smithRicardo-Arges: after a quick look, if all you need is the parsing, clj-tagsoup will be much simpler
08:44justin_smithescherize: no, not at all
08:44escherizeI'd agree with justin_smith here.
08:44justin_smithescherize: we are using reagent and sente, with a custom two-way router in cljc for communication over websockets
08:45escherizere-frame helped me a lot re: how to structure
08:45escherizethat's awesome!
08:45escherizeI wrote a chatroom toy to mess with sente last weekend
08:45escherizesuper cool stuff.
08:45escherizere-frame doesn't talk to the server at all
08:45Ricardo-Argesjustin_smith: Thanks, I am using enlive already since I use it for part of the scraping... it just hadn't occurred to me to use it to transform it into hiccup-like format. Tool myopia.
08:45justin_smiththe cool part is that with a little bit of abstraction, I can use the same namespace for the frontend and backend websocket routing
08:46justin_smithRicardo-Arges: ahh, OK.
08:46escherizeis it opensource? :3
08:46justin_smithescherize: we plan to make it open source, it is kind of tangled in a proprietary app right now
08:46justin_smithjust needs some refactoring basically
08:46escherizere-frame doesn't talk to the server. it's a cljs library that sits ontop of reagent and helps you maintain state.
08:46justin_smithahh
08:47escherizethere are 4 main parts
08:47escherize1 db: all the app's state kept in one place (like usual right)
08:47escherize2 subscription: kind of like a materialized view into the db
08:48justin_smithescherize: one pattern we have started on that I really want to get working before publishing the lib is -- if you tell the backend to send some data to {:foo {:bar {:bazes [...]}}} in the state map, and there is an error, it will put the error in {:errors {:foo {:bar {:bazes {:description ... :context ...}}}}
08:48escherize3 view: the reagent stuff -- uses subscriptions to get data and uses 'dispatch' to edit the db
08:49justin_smithwe need the support code that really handles those errors, and ties the error handling setup into the creation of the request
08:49escherize4 handlers: kind of like stored procs on the DB, contain all the details about how to do what needs to be done
08:50escherizeerrors in channels (and websockets i assume) has been tricky for me.
08:50justin_smithescherize: interesting. We have another layer -- the "private and external apis we abstract over", which are enough for a fleshed out back end.
08:51justin_smithescherize: the idea is that the router has a top level try/catch, and if anything gets that far up without being caught, it gets sent to a path in the frontend state map that mirrors the original desired path(s)
08:51justin_smithevery request to the router has two paths - the routing path, and the "place" it will update when it finishes the round trip
08:52escherizeround trip = back to server?
08:52justin_smithround trip = back to client
08:52escherizeI see
08:52justin_smithclient says "call :foo/bar on the server, put the result in [:foo :bar :bazes]"
08:53justin_smithend result is either {:foo {:bar {:bazes [...]}}} in the state map
08:53justin_smithor, {:errors {:foo {:bar {:bazes {:descritpion ... :context ... :etc ...}}}}
08:54escherizeI see. and that's handled by some top level function on the incoming channel on the client?
08:54justin_smithon the server
08:54justin_smiththe server discovers the error, so it alters the path
08:55justin_smithwhich is just edn that round trips
08:55escherizeright
08:55justin_smithso the client can establish two components - one watching the desired path, one watching the error path
08:56justin_smithand I think with a bit of mental pretzaling, I can establish the error handling in the same code that does the request
08:56justin_smithwith the help of a generic error watcher component maybe
08:56escherizewhile it's cool, I'm not actually a fan of using cljc for stuff that's not super simple.
08:57escherizeI found the sente example using cljx pretty rough
08:57justin_smithif nothing else, putting results under :errors if there were unhandled exceptions works. So I can make a component that creates a red flag on the page (literally?) if any errors are there, and let handlers remove them
08:57escherizethis is what I do, but with request/response
08:57justin_smithescherize: the key is figuring out what part of the logic can be that abstracted, of course
08:58escherizeI can see an argument for it: it's kind of a symmetric problem
08:58justin_smithI realized I had a lot of duplicated code in my client side and server side sente routers
08:58justin_smiththat's why I pulled it into cljc
08:58escherizei.e. cljs -> clj usually looks like clj -> cljs
08:59escherizehow are you finding sente
08:59justin_smithbut it was only when I separated routing from everything else that they became so similar
08:59escherizeI havn't used it but for a toy project
08:59justin_smithit's good, there were a few differences between client and server that I had to make some small shims for
08:59escherizeyes, i think a router abstraction is really a good choice there
08:59justin_smithbut other than that it has been great
09:00escherizeand passing data back and forth = ++
09:00justin_smithI do wonder now what using raw websockets look like (and would need to do that before I really know how good sente is), but using it has been great
09:01escherizeYeah, a friend of mine is using pure websockets + channels with aleph
09:01puredangerwasamasa: did you have a question re ops?
09:02escherizeis this still a hot topic: https://news.ycombinator.com/item?id=9511207
09:02wasamasapuredanger: yeah, there's still a spambot in here
09:02wasamasapuredanger: www<tab>
09:02puredangerthx
09:03escherizewoah SwiftKey is made with clojure on android!
09:19Ricardo-Argesescherize / justin_smith : That _almost_ did the trick. Keywords are being stringified when being turned into Json, so I can't be 100% sure of when something was an honest-to-god string and when it was a keyword. For instance... [:p "Hello"] is turned into ["p" "Hello"].
09:19Ricardo-ArgesI can probably get away with expecting the first element on any list to have been a keyword. Need to check.
09:20tdammersI'd go with the convention that only hash keys translate to keywords
09:21tdammersso {"p": "Hello"} -> {:p "Hello"}, but ["p", "Hello"] -> ["p" "Hello"]
09:21tdammersvOv
09:26escherizeyeah, sadly json is inferior to edn
09:26escherizeit's probably not a good idea, but you could do something like ["__key__h2" "hi"] => [:h2 "hi"] on the client
09:27escherizeprobably a bad idea though :)
09:28escherizetdammers: maps might not work because you can have an odd number of items in a hiccp-y vector [:div {:width "10px"} "hi"]
09:28tdammersah hmm
09:28escherizebut Ricardo-Arges: probably transit is a good fit there have you checked it out?
09:28tdammersthen I guess the "forward" conversion is basically lossy, and you have no way to reliable reverse it
09:29escherizetrue that
09:29tdammersmy stance is that when that is the case you shouldn't even try
09:29escherizeit's a good stance
09:29escherizegood solution, with higher friction: introduce transit
09:29tdammersmaybe resorting to a different JSON encoding would be an option
09:29escherizebad solution with lower friction: roll your own unkeyworder
09:29Ricardo-Argesescherize: I was not aware of it, checking.
09:29Ricardo-ArgesThanks.
09:29tdammershrmph
09:30puredangertransit is (effectively) an extensible, caching, cross-platform JSON encoding
09:31escherizeare you in the states, puredanger?
09:31puredangeryes
09:31escherizeit must be early or late there. I guess it's early and you're in NC.
09:31escherizehow'd i do?
09:31puredangerI'm in St. Louis Missouri and it's earlier :)
09:31puredangerbut not that early
09:32justin_smithpdx, even earlier
09:32justin_smithwork starts in 2.5 hours
09:32escherizedamn guys, it's 1:32 AM in New Zealand.
09:32escherizepuredanger: you might not remember me but I was the guy at the Cider unsession at Conj who looked over and was like 'damn ur alex miller'
09:32puredangerha :)
09:33puredangerI'm just this guy
09:33escherizeikr
09:33escherizei think thats what u told me haha
09:34escherizeare there other clojrue librarys with this kind of annotation? http://ideolalia.com/aleph/literate.html#aleph.examples.http
09:34justin_smithescherize: that's the output of lein marg
09:34justin_smithmargenalia plugin for leiningen
09:35escherizewow I'll look into it
09:36justin_smithescherize: there's a link on the bottom of that page
09:36escherizemost useful meta artifact ive ever seen: https://fogus.github.io/marginalia/
09:36justin_smithhaha
09:46Ricardo-Argesescherize / justin_smith : For what it's worth, turns out you can do [:li {:dangerouslySetInnerHTML {:__html "The text here"}}]
09:46justin_smithRicardo-Arges: woah - I guess it's intentional that it's that ugly
09:47Ricardo-Argesjustin_smith: And clearly named too.
09:48escherizeHaha. how'd you find that out Ricardo-Arges?
09:50Ricardo-Argesescherize: Looking into the reagent code.
09:50Ricardo-Argesescherize: https://github.com/reagent-project/reagent/blob/19a384443f6353875cc4a0eef468e45f5411d2c5/demo/sitetools/core.cljs#L161-L162
09:50escherizethanks for the link
09:55wasamasaI must be overlooking something really obvious, but how do I turn a keyword into a string?
09:55bacon1989,(name :test)
09:55clojurebot"test"
09:55escherize,(name :namespace/test)
09:55clojurebot"test"
09:55wasamasathanks
09:55escherizeprobably won't matter tho, wasamasa
09:55wasamasaso there's no generic to_string thing like from java
09:56wasamasaor rather, it's used for different purposes
09:56bacon1989well, there's (str)
09:56bacon1989but yeah, it does funky things
09:56wasamasalike, displaying a human-readable variant of something more complex than a built-in data structure
09:56escherize,#(apply str (rest (pr-str % :keyword)))
09:56clojurebot#object[sandbox$eval74$fn__75 0x7349edac "sandbox$eval74$fn__75@7349edac"]
09:56escherize,(apply str (rest (pr-str :keyword)))
09:56clojurebot"keyword"
09:57justin_smith,(name :keyword)
09:57clojurebot"keyword"
09:57justin_smithoh, we covered that
09:57escherize,(apply str (rest (pr-str :namespace/keyword)))
09:57clojurebot"namespace/keyword"
09:57clojerRecords and protocols both have a self-referential first arg but I haven't seen any defrecord code which actually makes use of it. As such, might not "_" be a better convetion than "this" or "self"? How is the first arg customarily used, if at all?
09:57justin_smith,(subs (str :namespace/keyword) 1)
09:57clojurebot"namespace/keyword"
09:58escherizei should use subs more
09:58wasamasaname is exactly what I need, thanks
09:58escherize,(doc subs)
09:58clojurebot"([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive."
09:58justin_smithclojer: when I use stuart sierra's component lib, the arg gets called component and I use it extensively
09:59escherize(subs "this is cool! not!" 0 13)
09:59clojerjustin_smith: Ah, good. Do you have anything on Github I could look at?
09:59justin_smithclojer: since records are maps, the component system adds your deps as extra keys on the this arg
09:59TEttingernosesmith
10:00justin_smithclojer: https://github.com/stuartsierra/component#creating-components
10:01justin_smithTEttinger: yeah, that is me, but I think the official examples are better than anything I have in my public github in this case
10:01TEttingerheh, you're noisesmith though
10:01TEttingernosesmith has a very dirty keyboard
10:01justin_smithhha
10:03clojerjustin_smith: His first example begins with (defrecord Database [host port connection] .... I'm confused. I thought the first arg was like "this" in Java, ie. the object.
10:03justin_smiththe vec given to defrecord is its defined fields
10:03justin_smiththe first arg to its methods are this
10:04clojerjustin_smith: Of course. I was looking in the wrong place.
10:11powrtoc_clojer: I pass the this parameter onto other functions too - not all the time sure -- but often enoug
10:11powrtoc_h
10:12justin_smitha subset of the component usage: (some-method [this] (assoc this :frobbed true))
10:12justin_smithand then (other-method [this] (if (:frobbed this) ... ...))
10:30kaiyinhttps://gist.github.com/kindlychung/f16aaa240e7fc63f00ab#file-all-clj-L9 what is wrong with this macro?
10:31Bronsakaiyin: it shoouldn't be a macro
10:31Bronsa'(repeat nil) is true
10:32Bronsakaiyin: all = (partial every? identity), any = (partial some identity)
10:35kaiyin,(and (repeat nil))
10:35clojurebot(nil nil nil nil nil ...)
10:36kaiyinwhy doesn't it return false?
10:36Bronsawhy should it? a collection is not a falsey value
10:36kaiyin,(apply and (repeat nil))
10:36clojurebot#error{:cause "Can't take value of a macro: #'clojure.core/and", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6543]} {:type java.lang.RuntimeException, :message "Can't take value of a macro: #'clojure.core/and", :at [clo...
10:37Bronsaand is a macro, you can't apply it
10:37Bronsause every?
10:37kaiyinalright.
10:37Bronsa,(every? identity (repeat 5 nil))
10:37clojurebotfalse
10:37kaiyini see.
10:37Bronsakaiyin: this is not the issue in your example though
10:38kaiyinBronsa: what's the issue then?
10:38kaiyin~@ applied to a lazy sequence?
10:38clojurebotHuh?
10:38Bronsakaiyin: deh, nevermind.
10:39kaiyinWhat's clojurebot doing? Last time I saw it speaking Dutch.
10:39Bronsakaiyin: it looks like you're expecting your macro to work automatically on both varargs and collections
10:39Bronsaclojurebot: ??
10:39lazybotBronsa: What are you, crazy? Of course not!
10:39clojurebot? is !
10:40TimMckaiyin: clojurebot has a factoid engine that unfortunately (?) autopopulates from the chat on a random basis.
10:40TimMcOh, but I guess what you're seeing is it thinking that random statements are addressed to it -- in this case, a factoid lookup.
10:41kaiyinok
10:41kaiyinlooks cool, :)
10:41TimMcclojurebot: gfredericks?
10:41clojurebotgfredericks is a sexp wizard who only types transpositions
10:42kaiyinclojurebot: Bronsa
10:42clojurebotBronsa trusts me to recall all of clojure.core by heart
10:48TimMcclojurebot: TimMc?
10:48clojurebotTimMc is the other gfredericks
10:48TimMc\o/
10:49Bronsalol
10:52kaiyinclojurebot: waar kom je van daan?
10:52clojurebotGabh mo leithscéal?
11:00zoti have a stateful predicate function … filter docs say "pred must be free of side effects." what's the 'right way', instead of filter?
11:02aderethDoes any other code affect the state? Are you relying on it being in a particular state at the end of the filtering?
11:02andyf_zot: I think I'd just use filter, as long as I understood that sometimes lazy sequences have more than the minimum necessary evaluated in order to produce their results. If that is bad for your side effects, be cautious of that.
11:03gfredericksTimMc: well botted
11:03zotthis is testing code, and the results are immediately eval'd, so i figured it to be safe here. and yet, i wondered if i misunderstand.
11:05mpenet(doseq [... :when ...]) is probably cleaner
11:07kaiyinis there something like this builtin in clojure? (defn truthy? [expr] (if expr true false))
11:08hyPiRionkaiyin: boolean
11:08kaiyincool
11:08hyPiRion,[(boolean 2) (boolean nil)]
11:08clojurebot[true false]
11:08gfredericks,(boolean boolean)
11:08clojurebottrue
11:10zotmpenet: i was checking the do family, but i need the return value, not just the side effects; (for [… :when] …) seemed more natural
11:18kaiyinBronsa: well, this seemes to be working: https://gist.github.com/kindlychung/8423af12c554e0abdf66
11:36kaiyinhttps://gist.github.com/kindlychung/e59a3a607fcf4ac5a71e Why isn't ~(count match-expression) evaluated to 2 here?
11:36kaiyin,(let [x [1 2]] `(= 3 ~(count x)))
11:36clojurebot(clojure.core/= 3 2)
11:40oddcully,(count [1 2])
11:40clojurebot2
11:40oddcullybecause the vector holds two items
11:41oddcullyoh "why not"... sorry... all the macrofoo...
11:50john_atxI just installed leinigen on Ubuntu 15, but I can't create a new ring project
11:51john_atxif I do "lein new ring test", I get Failed to resolve version for ring:lein-template:jar:RELEASE: Could not find metadata ring:lein-template/maven-metadata.xml in local (/home/john/.m2/repository)
11:51john_atxAny ideas on that one?
11:59john_atxah, changed it to lein new compojure test
11:59john_atxnow its workign
12:00oddcullyif you say "installed on ubuntu" you mean via wget and via apt-get?
12:01oddcullychances are good, that you get some incredible old stuff via your distribution and you should in that case check the versions
12:14justin_smithjohann: agreed with oddcully - leiningen is better at managing its own deps (including its own version) than ubuntu is at managing lein, better to install by downloading the lein script and put it in your path (disregard of course if this is how you installed it)
12:15justin_smitherr, john_atx left, sorry
12:15johannjustin_smith: you are forgiven lol
12:29alandipertdoes anyone recall an odd thread on clojure dev maybe a year ago wherin people publicly willed contributions to clojure? it was some kind of legal library absorption ritual
12:32alandipertpuredanger, perhaps you would recall? ^^
12:32puredangeryes
12:33alandipertpuredanger, this is re: http://dev.clojure.org/jira/browse/DPRIMAP-8
12:34alandipertthere are 4 contributors, all have CA signed, all probably willing to help - thanks for advice!
12:34puredangerthere is a statement we ask each contributor to make when they donate a whole library into contrib, like https://groups.google.com/d/msg/clojure-dev/3kT3Pijwjrk/4-BijVCTMwcJ
12:35puredangerwould be cool to see that stuff get added
12:35alandipertpuredanger, great, thanks, i will cajole
12:36puredangerI am not sure what build hurdles exist for building/testing/releasing clj/cljs libs in contrib process
12:36puredangerthat's new ground
12:37puredangerif only there were a build tool where I could create customized task pipelines
12:38alandiperthehe
12:39andyf_alandipert: data.priority-map has already gone through that legal process long ago, has it not?
12:39andyf_It should not need to repeat that.
12:39andyf_Oh, you mean the ClojureScript version?
12:39alandipertandyf_, it has, but the contributions in question were to an unofficial port
12:40andyf_If they can be made into patches for data.priority-map, and all authors have signed CAs on file, that would do it?
12:43alandipertandyf_, possibly, but it sounds like more work. i think it's probably easiest for daniel compton to be able to use the port as a reference as he pursues unifying the two
12:43alandipertandyf_, as i'm not sure any one patch would necessarily end up in the final result
12:44alandipertpuredanger, i'm game for boot-age
12:45alandipertpuredanger, one thing that would be easy-ish is running 1.7 in a pod and disappearing .cljc as a build step
12:45puredangerwell, it's something I've thought about a bit and I think it would be pretty great, but Rich would have to ok using it since it's non-contrib
12:47puredangerI grow weary of the Maven but there are a few things in the current setup where we would need to patch some gaps. In particular releasing to Maven central with GPG-signing and artifact signatures
12:47puredangerI'm certain that's achievable but would probably need a bit of effort
12:47puredangerI'd really like to get async off of its bespoke build process too
12:48alandiperti am happy to help but one glaring difference would be, boot doesn't work well in windows, which i imagine would deter contributors to whatever library its used on
12:49alandipertwhich is not to say windows champions won't emerge, they just haven't yet
12:49alandipert(in force)
12:52alandipertpuredanger, anyway i gotta go but i'll get a thread going re: priority-map
12:52puredangergood to know, thx
13:10Bronsapuredanger: ^
14:27wasamasalol
14:28wasamasahow clever
14:40Steve_Milleranyone know a selmer tag library someone already wrote and made available? for html forms.
15:12wxlanyone know of forum software built in clojure?
15:24dnolenClojureScript 0.0-3255 released https://groups.google.com/d/msg/clojurescript/A--qv0JxfO8/FoCzLNQ-D4EJ
15:26tatutdnolen: awesome!
15:27dfletcherMan. Was playing with a fib impl for fun and wondered how others did it. Found http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci#Recursive_Version ... Dang. Been doing this thirty years. Aaaand Clojure teaches me I've been thinking about recursion backwards that whole time. <3
15:31amalloydfletcher: well, data recursion as opposed to algorithmic recursion is rather fiddly, in clojure
15:31amalloyit works great in haskell, but the simple version only works in clojure because you're leaning on the global-mutable fib-seq. it's not practical for actually using fibonacci numbers, because you can't GC the seq as you walk through it
15:32dnolenah forgot to add that with this release, ClojureScript and all its Clojure dependencies are now available as AOTed artifacts
15:32amalloytry writing it as a function that returns a fib seq, dfletcher, as an exercise. you'll probably want to use ##(doc promise)
15:32lazybot⇒ "([]); Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to deref/@ prior to delivery will block, unless the variant of deref with timeout is used. All subsequent derefs will return the same delivered value without blocking. See also - realized?."
15:34dfletcheramalloy, huh well there is a "Properly Scoped Version" on that page that seems alright
15:35dfletcheranyway I just mean conceptually. there is a different way than just "top down, wide scope towards narrow", the opposite of that (corecursion) and it's really compelling in some situations.
15:35amalloydfletcher: oh, it is. but it's a totally different technique: recursion through a function, instead of data with recursive pointers into itself
15:37bacon1989dnolen: what do you mean by them being Ahead-Of-Timed artifacts?
15:37bacon1989also, great work porting pprint, that's awesome!
15:38dnolenbacon1989: they won't be compiled on the fly, ClojureScript is no longer a small library, loading a REPL required compiling 12000 or 13000 lines of Clojure
15:38dnolenbacon1989: I didn't port pprint thank Jonathan Boston & Shaun Lebron
15:39bacon1989dnolen: in the long run, does this mean we could have a clojure repl live directly in javascript?
15:39bacon1989or are you suggesting that only bits and pieces of the clojure.core are included in a javascript output?
15:39bacon1989sortof like advanced pruning?
15:42dfletcheroh right amalloy btw my original version did return a function but not quite like you described. is the following legit?
15:43dfletcher,((defn fib [n] (letfn [(f [x a] (if (= x 2) a #(f (dec x) (conj a (apply +' (take-last 2 a))))))] (trampoline f n [0 1]))) 10)
15:43clojurebot[0 1 1 2 3 ...]
15:43amalloyuh, aren't you holding the entire fib seq in memory forever there?
15:44amalloylike, (last (fib 1e8)) will run out of heap
15:44dfletcherno it builds and returns a vector
15:44amalloyright: it's not lazy
15:44amalloyit's fine, although quite inefficient, as an eager recursive solution
15:45dfletcherit's the procedural poison in my brain that needs expunging :>
15:47gfredericks~it's |the| procedural poisin in your brain that needs expunging
15:47clojurebotOk.
15:53TimMcOh no, a typo!
15:53TimMc<commence 5 minutes of fighting with clojurebot>
15:55lodinIs there any way to add a Clojure lib to a lein project without going through some kind of centralized repo? Like having it in ./dependencies in the project directory.
15:55TimMcThere is, but it will lead to sadness.
15:55dnolenbacon1989: if you're not familiar with Clojure AOTed artifacts I wouldn't worry about this too much :) no has nothing to do JavaScript at all
15:55dnolenother than ClojureScript compiling to it
15:56lodinTimMc: How? (And why?)
15:56TimMclodin: This page has some pointers: https://github.com/technomancy/leiningen/wiki/Repeatability
15:56TimMcWhat's the use-case?
15:57TimMcProprietary stuff?
15:58lodinTimMc: That, plus maximum repeatability.
16:01TimMclodin: What's the situation you're worried about? Repos going down?
16:05lodinTimMc: For instance, yes. Or just need for offline installation.
16:06lodin(Yes. Offline is still a thing.)
16:26TimMclodin: I code offline plenty, but I just run lein deps beforehand. (Doesn't help with plugin-added dependencies but it covers most cases.)
16:29TimMclodin: Offline installation... do you mean deployment on a machine that will be offline?
16:32kaiyinI want to define a function f so that (f (inc 1)) returns '(inc 1), how can i do that?
16:35lodinTimMc: I don't have that problem currently, but before I've had such setups so part of the question is just for future reference. I know you can make a standalone jar, so that helps a lot, as long as you don't need to do any patching then and there.
16:38kaiyin,(defmacro f3 [& body] (quote `(~@body)))
16:38clojurebot#'sandbox/f3
16:48lodin|awaykaiyin: Or (defmacro f [form] (list 'quote form)).
16:53cmcfarlenI ran into this issue with fressian causing problems: (type (fressian/read (fressian/write [1 2 3 4]))) => java.util.Arrays$ArrayList (i.e. conj doesn't love this). Looking into this and similar has been reported as a bug, but is adding a custom 'list' reader the way to go for getting the same round-trip types?
16:56jtmarmonhey yall. i'm trying to wrap my head around the various choices for dependency injection as it seems the literature in the clojure community is pretty undecided on this. it seems like perhaps the simplest way to share, for example, a database connection object, is to put it in its own namespace and :require that in all files that need to perform database operations. is this correct/a common way of handling shared state? thanks!
16:57geirby(was going to disconnect but now I need to watch this)
16:57justin_smithjtmarmon: use stuartsierra's component library
16:58justin_smithand provide the database as a component
16:58jtmarmonyeah i've taken a look at component as well. it just seems like a bit of an extensive solution for say a hacked together web app. is there really no standard way for handling this without component?
16:59justin_smithjtmarmon: without component, just make it a global, and require the namespace
16:59justin_smithlike you first suggested
16:59gfredericksand pray your app never has to get more complicated
16:59jtmarmon> "a global" what does this mean exactly? and lool gfredericks this is actually for an ETL tool so it'll get used once and never touched again :P
16:59justin_smithexactly. It's easy to start out with component. Taking a complex app and "componentizing" later can be a huge pain.
17:00justin_smithjtmarmon: top level defs, all defs in clojure are global mutable objects.
17:00jtmarmongot it. thank you :)
17:01gfredericksjtmarmon: somebody will figure out a way to twist it into a crucial core business product
17:02jtmarmon"disgusting mess of an ETL script in clojure...as a service"
17:02jtmarmonbezos is coming for me :x
17:02lodingfredericks: Can you elaborate on what "more complicated" means in relation to component? (I've never use component myself; seen the video though.)
17:04gfrederickslodin: more complicated things like needing several database connections, or just a large variety of inherently stateful resources that you need to keep track of
17:05lodingfredericks: Isn't that exactly the problem component is supposed to solve? :-)
17:05jtmarmonlodin: gfredericks is saying that if I use globals I should hope that my app never gets more complicated, otherwise i _will_ need component
17:06lodinOh. I connected the "and" to the wrong line. :-)
17:10gfredericksyep
17:16justin_smithyeah, I just componentized our main app, and the ability to define a function that safely stops all resources (if running), reloads all changed files, then restarts the services, without exiting the repl or worrying about straggling state, is awesome
17:25gfredericksstraggling state is for wusses
17:28justin_smithclojure.tools.namespace.repl/refresh-all is what separates us from the apes
17:28gfredericksI haven't gotten into that yet
17:29gfredericksI assume it will solve all of my protocols+records reloading problems
17:29justin_smithit solves the ones that come from libs outside your project
17:30justin_smithgfredericks: with my own project - all records belonging to my own app that interact with state are introduced by the component system, so I can safely redefine them. and refresh-all doesn't reload eg. core.async and thus break their defrecords / defprotocols
17:33justin_smithnow if I had eg. a big queue or something stored in an atom that wasn't reset by a component restart, I could see this problem still happening. But as long as my system is a defonce, in practice I think the problem is always preventable
17:33akkadanyone do db migrations that are backward compatable?
17:46lodinI think it's an interesting phenomenon that everyone loves the immutable data structures, but many are so fast to reach for the mutability of namespaces when the code grows beyond functions and into applications, which is where the need to be able to reason about the code is even more important. And not just for state, but for configuration or avoiding to pass an argument around, effectively trading simple for easy.
17:48gfredericksI think that happens because you're not using OOP and so there's not any other easy way to do it
17:48gfredericksglobals are all you have
17:50kaiyinwhat are the prerequisites of reading this paper? http://moscova.inria.fr/~maranget/papers/ml05e-maranget.pdf
17:52ambrosebskaiyin: I found it pretty self contained.
17:52ambrosebskaiyin: have you tried to jump in?
17:52lodingfredericks: I sometimes got the feeling, a few years back anyway, that people were really sick of Java OOP so passing a configuration object as the first argument, effectively writing your functions like (defn f [this & args]) was shunned, even though it sometimes was the proper thing to do.
17:53ambrosebskaiyin: you can browse core.match for an implementation
17:53ambrosebskaiyin: and turn on all the tracing stuff
17:53kaiyinambrosebs: trying. what is the tracing stuff?
17:56ambrosebskaiyin: I forget but IIRC there's a few flags to turn on in the core.match implementation to step through the algorithm
17:56lodingfredericks: As I see it, the thing with component is that it "reintroduces" objects in Clojure (and helps you with ordering). :-)
17:56ambrosebsalso some high level docs in the main clj file
17:58kaiyinambrosebs: ok, i'll look it up.
18:21kaiyinambrosebs: i don't quite understand the occurrences notation here: http://i59.tinypic.com/4qqzh0.jpg could you help me a bit?
18:23lodinjustin_smith: What were the major pain points when you componentized your main app?
18:48ambrosebskaiyin: looks like it's a way to dig into subterms in a pattern
18:48ambrosebs(cons (cons 'a 'b) 'c)/1/2/ /\ should be 'b
18:49ambrosebserm imagine that's zero-indexed
18:50ambrosebswait no, maranget uses 1-indexing here
18:51ambrosebskaiyin: that help?
18:51kaiyinambrosebs: very much, crystal clear now.
18:51ambrosebsgreat
18:52kaiyindoes this apply only to cons list?
18:52kaiyinor can it be generalized to vectors and maps?
18:55ambrosebskaiyin: all ML constructors are represented as c(1 ... k)
18:55kaiyinok
18:56ambrosebsread the start of that section
18:56ambrosebstalks more about c
18:57kaiyini see.
18:57kaiyinthanks a lot.
19:27justin_smithlodin: it took a while to ensure that things which get called at runtime would all be able to get components passed in as needed
19:28justin_smitherr, better way to put that was ensuring that everything could have components passed in at runtime
19:34gdevhttps://www.refheap.com/100759
19:35gdevusing a map with a hashtag anonymous function is perplexing me
19:37hiredman,'#({:a :b})
19:37clojurebot(fn* [] ({:a :b}))
19:37hiredman,'(#({:first-name %1 :last-name %2} "foo" "bar") "baz" "bang")
19:37clojurebot((fn* [p1__49# p2__50#] ({:first-name p1__49#, :last-name p2__50#} "foo" "bar")) "baz" "bang")
19:39hiredmanif #(+ %1 %2) is a function that immediately applies the function + to the first and second argument, what does that make #({:a :b}) ?
19:40hiredmanif (let [f +] #(f)) is a function that invokes + with no args, then what is (let [f {:a :b}] #(f)) ?
19:42gdevmy repl says it's a function
19:43hiredmanyeah, but what does it do when you invoke it?
19:43hiredman(this is not a trick a question)
19:43gdevarity exception
19:44turbofail,(#(hash-map :first-name %1 :last-name %2) "Foo" "Barson")
19:44clojurebot{:last-name "Barson", :first-name "Foo"}
19:44hiredmanif #(FOO) returns a function that immeidate invokes whatever foo is as a function, then what is going to happen when FOO is a map?
19:44hiredmanimmediately
19:45hiredman(it is going to invoke the map as a function)
19:45lodinjustin_smith: How was it structured before component?
19:46hiredman(clojure maps are functions, taking 1 or 2 arguments, so of course when you invoke it with no arguments you get an arity exception)
19:46gdevOkay I see now
19:46justin_smithlodin: stateful objects in the top level defs, with init functions that bound / created their contents
19:48justin_smithlodin: on a per-case basis, either a promise, or an atom, or a regular def
19:51lodinjustin_smith: I see.
19:51justin_smithlodin: a bonus with component is jsvc integration became much simpler
19:53lodinjustin_smith: How's that?
19:54justin_smithlodin: jsvc exposes hooks from your app for start / stop / refresh, and this integrates nicely with the lifecycle protocol
19:54lodinjustin_smith: Ah.
20:13ben_vulpeshow would i go about using code from a leiningen plugin (eg https://github.com/montoux/lein-less) in my own clojure code?
20:14ben_vulpesnaively requiring 'leiningen.less fails
20:14justin_smithben_vulpes: have you tried requiring it as a normal dep?
20:14justin_smithplugins are available in the lein process, but not in yours. But you should be able to add it to your project.clj in the deps section
20:15ben_vulpesmyeah, i have [lein-less "1.7.2"] in my :dependencies, but then calling (use 'leiningen.less) fails to find the right classes
20:16justin_smithben_vulpes: because of plugin weirdness, you may need to require its deps https://github.com/montoux/lein-less/blob/master/project.clj#L13
20:16justin_smithprobably leiningen-core should suffice?
20:16ben_vulpesshmooookay
20:17ben_vulpeswao :optional :true that's a scary thing to see
20:17justin_smithnow that I think about it, that makes sense - as a plugin it should use the lein and clojure that pulled it in, and not specify its own
20:18ben_vulpesbetter..."could not locate leiningen/compile__init.class or leiningen.compile.clj on classpath"
20:47ben_vulpeshow would one go about accessing a clojure project.clj at runtime?
20:48[mad]hi
20:50xeqiben_vulpes: thats hard. Some steps would include leininegen-core and using l.c.project/read on the project.clj from the classpath. What are you trying to do with it?
20:54xeqiben_vulpes: https://github.com/taoeffect/slothcfg looks like it will help
20:54ben_vulpesi'm hooking less compilation into the reloaded workflow, want to specify less source and output dirs in the common place, and use those both in the reloaded workflow and in jarification
20:54ben_vulpesxeqi: ^^
20:56ben_vulpesxeqi: l-c.p/read looks to do the trick. thank you!
21:31gfredericksis there a builtin way to get the index of the lowest set bit in a Long?
21:32gfredericksI'm trying to write my own and am getting the feeling that I'd have to use java to get the best bytecode for it
21:33gfredericks(I was going to do a binary search, which I guess is 6 steps or something)
21:35hiredmanhow can you do that as a binary search?
21:35gfredericks(if (zero? (bit-and x 0xFFFFFFFF)) (it's in the upper bits) (it's in the lower bits))
21:36hiredmanoh
21:36hiredmananyway
21:36hiredmanhttp://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#numberOfLeadingZeros%28long%29
21:36gfredericksoh hey yeah
21:36gfredericksI was just scanning that page and swore that nothing applied
21:36gfredericksthanks
21:37gfredericks(inc hiredman)
21:37lazybot⇒ 78
21:37hiredmanand I sort of assume that method has an intrinsic in the jvm, but who knows
21:38gfredericksif it doesn't I doubt I can do better on my own anyhow
21:50TEttinger(inc hiredman)
21:50lazybot⇒ 79
22:23mysamdogSo I have my repl set to start in the namespace atm.core, and atm.core requires atm.db. I had a mistake in atm.db (I meant to have a vector, but I put curly brackets around it to make it a hashmap)
22:24mysamdogWhen I ran the repl with 'lein trampoline repl' I couldn't call any functions in clojure.core or anything that is part of my project
22:25mysamdogBut if I did 'lein repl' it not only told me what was wrong with my code, but it also loaded clojure.core. What about trampoline causes this?
23:13Niachow to use createImage method in java.awt.Toolkit?
23:14NiacI try to use proxy ,but something is wrong