#clojure logs

2013-11-13

00:00tbaldridgeI'll try duplicating that and see how it goes
00:00dnolentbaldridge: since macroexpand-1 hands the form to you the CLJS hasn't even touched what we got from the reader yet.
00:00dnolenCLJs compiler
00:11grncdryay :D
00:13eggheadwow, core.async has gotten a lot cooler with this new api
00:14egghead(->> (spool source-seq) (map< transform1) (map< transform2...))
00:15nonubywith immutant is there a way to use immutant session store without the web app code taking a direct dependency on immutant.
00:20tbaldridgeegghead: spool is in the core.async now, called "to-chan"
00:20tbaldridge*is in core.async
00:22swarthyafter I call line-seq is there a way to rewind the reader?
00:24swarthyreframed: how do I make the following work, https://www.refheap.com/20792
00:24swarthyright now total2 is 0, should match total
00:25eggheadoh, thanks tbaldridge
00:26justin_smithswarthy: line-seq consumes the whole file if you realize it
00:26justin_smithyou need to reopen or rewind the file to read it again
00:26justin_smithbut if the file is not altered, just reuse the first line-seq?
00:27justin_smith*consumes the whole stream
00:27swarthyjustin_smith: the example was trivial, in reality i first consume it all to get the full count. Then filter the line-seq on the second pass to count only lines that match a regex.
00:27swarthyI guess I need to loop/recur maybe and do both at once.
00:28justin_smithwhy not just save the output of line-seq and then iterate it as many times as you need?
00:28justin_smithie, suck the whole thing into a binding, then iterate on the binding
00:28swarthyhmm. Its a million line file, still do that?
00:28justin_smithoh, never mind
00:28justin_smithrewind or recreate the reader :)
00:29justin_smithwell, million line may be OK, but may as well check
00:29justin_smiththere is a .reset method on some input streams
00:29swarthyyeah. I guess a less idiomatic but better way would be to loop/recur and count all + count matches yes?
00:29swarthyyeah BufferedReader ie: line-seq doesn't have reset
00:29swarthyso I suppose I have to just recreate it if I take that method
00:29justin_smithyeah I think so
00:30justin_smithif you need the whole count from the beginning
00:30justin_smithalso, if you just need the line count, there are faster ways to do that without turning every line into a java.lang.String
00:30swarthyYeah that is likely true
00:31swarthyI need a total line count, and then lines that contain some regex match.
00:31swarthySo I can come up with a percentage.
00:31justin_smithsomething that just searches the inputstream for the bytes matching a newline, not creating any objects just incrementing a counter, would be much much faster for huge files
00:32justin_smithso you can't do the count and count matching regex in parallel?
00:32justin_smithif you just need a percentage, just build up two counters
00:32bitemyappjustin_smith: you know https://github.com/caribou/caribou-frontend/blob/master/src/caribou/app/request.clj isn't async-safe right?
00:32swarthyhttp://stackoverflow.com/questions/1277880/how-can-i-get-the-count-of-line-in-a-file-in-an-efficient-way
00:33bitemyappand that it's pretty icky to write code that relies on having a dynamic var like that in scope?
00:33bitemyapp`cbp: ggs.
00:33`cbp:-)
00:33lpvbis there a function to make a vector of bits from a numeric type
00:33lpvbor should I write it myself
00:33lpvbbitemyapp: I miss hoogle
00:34justin_smithswarthy: (reduce (fn [[total matching] line] ...) (line-seq input))
00:34bitemyapplpvb: sigh, yeah...me too.
00:34justin_smithbitemyapp: thanks for that suggestion, I don't know why that is being done that way
00:34justin_smithbitemyapp: each request should have just one thread while being handled - but of course we cannot take that for granted
00:35bitemyappjustin_smith: you can't and the current async models for Ring don't guarantee that.
00:35bitemyappjustin_smith: rather the opposite, http-kit doesn't use thread affinity or do anything to thread locals, so you have to write clean code.
00:35`cbplpvb: maybe in java.nio
00:35justin_smithI don't even use wrap-request-map myself - is it in the default caribou template's core handler?
00:35bitemyappI've been trying to nuke uses of dynamic vars in Ring libraries.
00:35justin_smithcool
00:36`cbplpvb: make a byte array then put an integer in it
00:36`cbpa ByteBuffer
00:37justin_smithbitemyapp: the real problem is likely wrap-caribou, which is used to create the config context that should surround all the request handlers (for db connection, s3 auth, etc.), I think that is a dynamic var :(
00:37`cbpI meant
00:37bitemyappjustin_smith: yeah that's not kosher at all outside of Jetty.
00:37bitemyapp / tomcat.
00:37justin_smithgotcha, thanks
00:37justin_smithwe will do some workshopping of this issue, we do want to get this stuff right
00:38bitemyappjustin_smith: you want to plan ahead for async safety, the moment you need websockets or long polling for something, you have to be able to pick up and drop thread context at will, static globals only, local argument passing and closures otherwise.
00:39justin_smithright, that is going to be a mess of a rewrite in caribou.model, but it will be needed
00:43coventryIs there a way to package a third-party jar into my jar? Is this what lein uberjar does, and if so, is there a way to do it selectively?
00:45coventryI've built my app off [tools.reader "0.8.0-SNAPSHOT"]. Somehow, I got a jar for this, but "lein deps" from a fresh maven repository doesn't find it anymore.
00:45coventryI'm depending on a feature which is in that but not in 0.7.10, the latest version, namely metadata giving the end-positions of forms.
00:46justin_smithbitemyapp: wait, if we want a binding of a variable to be per-thread, isn't that an apropriate usage of a dynamic var?
00:46swarthyjustin_smith: thanks for the input. I'm about 3 months into my clojure journey and your recommendation to use reduce blew my mind a bit, but it works great!
00:47bitemyappjustin_smith: thread scope isn't a meaningful scope in async applications.
00:47justin_smithahh, yeah
00:47bitemyappjustin_smith: don't abuse it as such. There are proper FP ways to form a real scope that doesn't rely on an implementation detail that will blow up in your face later.
00:48justin_smithyeah, so everything that needs the db config needs to be wrapped so it can be created in scope of that config
00:48justin_smithin order to capture it
00:48bitemyappjustin_smith: database stuff shouldn't be global, let alone thread scoped.
00:48justin_smithmaybe promises would help that be less of a mess to change
00:48bitemyapp :|
00:48bitemyappno. stop.
00:49justin_smith?
00:49lpvbwhy are the latest clojuredocs.org only 1.3
00:49bitemyapplpvb: *sigh* long story...
00:49bitemyapplpvb: it's a rails app, un-maintained by somebody that went AWOL
00:49lpvbhe owns the domain?
00:49logic_progis there any clojurescript web rtc demo?
00:50bitemyappjustin_smith: for one thing, db config implies a few things to me. One that sticks out is that you're assuming a global singleton database.
00:50bitemyappthat is deeply troubling.
00:50lpvbshouldn't there be a place to download the docs like scala
00:51justin_smithbitemyapp: it is reentrant, I can use multiple db configs in a repl in one running app
00:51justin_smithbut we are maybe doing the re-entrance wrong
00:52justin_smithI mean db-config as one of the ones available
00:52bitemyappthe database should be a resource you just pass to the dependent functions
00:52bitemyappas an argument
00:52coventryHow evil is it to deploy an uberjar to clojars?
00:52bitemyappcoventry: do it, and an angry mob will burn your house down, with you in it.
00:53coventryOh, I know, I'll deploy the version of tools.reader I need.
00:53bitemyappcoventry: that's the ticket.
00:55justin_smithmaking a generator that takes a config and makes a configured version of each function would be less extreme a rewrite
00:55justin_smiththen populating the functions we need from the generator
00:55bitemyappI generally just pass a db conn or value to the dependent functions, depending on the semantics of what they're doing.
00:56bitemyappI don't find I need the generator pattern for this particular case.
00:56bitemyappI do use let over lambda, but not for that.
00:56justin_smiththe issue is the db namespaces are huge
00:57justin_smithand the rewrites needed to change every function that calls a db function to take that extra arg would be pretty extreme
00:57justin_smithhmm... maybe it's not as bad as I think
00:57justin_smithit will need some pondering
00:58coventryHmm, it appears that 0.8.0 is available, but lein is not seeing it. https://oss.sonatype.org/content/groups/public/org/clojure/tools.reader/0.8.0-SNAPSHOT/
00:59justin_smithcoventry: have you added that repo to your config? you may need to do that manually for sonatype
00:59coventryjustin_smith: How would I do that. I don't recall doing so.
01:00justin_smithhttps://github.com/technomancy/leiningen/blob/master/sample.project.clj#L74
01:00justin_smithlinked line, 74
01:00coventryI don't have that in the context where I got the 0.8.0 jar, but I'll try it out. Thanks.
01:03bitemyapparrdem: http://i.imgur.com/ixhJfW8.jpg
01:05coventryI'm still getting "could not find in clojars", with the following in my profiles.clj. Am I doing it right?
01:05coventry{:user {:repositories [["sonatype" {:url "http://oss.sonatype.org/content/repositories/releases&quot;}]]}}
01:06justin_smithcoventry: yeah, that looks right
01:07arrdembitemyapp: lolz
01:08justin_smithbitemyapp: so by that same reasoning shouldn't *out* be an explicit arg to every function that prints?
01:09bitemyappjustin_smith: stdout is global because of POSIX
01:09bitemyappjustin_smith: take ownership for the design choices that are actually a choice
01:10bitemyappdon't try to use something like that as an excuse.
01:10arrdembitemyapp: there are people who want to live with me next year. that is why I won't be.
01:10bitemyapparrdem: *snorts* what?
01:10bitemyapparrdem: I live with 12 people.
01:15arrdembitemyapp: see.... that is why I'll never live bay/valey area if I can help it.
01:16arrdembitemyapp: COL is just friggin stupid
01:20bitemyapparrdem: I'm plotting my escape already. I'm figuring out if remote working with my company is possible.
01:20bitemyapparrdem: even thinking of visiting Austin to see what it's like there
01:20bitemyappmostly thinking of Austin, Seattle, and Portland.
01:21justin_smithPortland is nice, especially if you don't like driving a car or needing to own one
01:22arrdemjust got back from a seattle visit, I could see myself in seattle or austin for the long haul. never been to portlandia tho.
01:23bitemyappjustin_smith: I like cars and motorcycles.
01:23bitemyappand beef. I'm not very environmentally friendly.
01:31bill610I'm using luminus. From the repl, I run (start-server), which starts the server and opens a browser tab. Cool. When I make a change to the route function and run (use 'mynamespace :reload-all) in the repl, I go back to the browser and see that my changes have not taken affect. Should that work?
01:32justin_smithbill610: the handler is being used as a value by ring, not resolved from a var
01:32justin_smithyou can use #' to pass in a var instead of its value
01:32justin_smiththere is a wrap-reload middleware that helps with this stuff too
01:34bill610justin_smith: so, reload-all won't do what I'm expecting when running the out-of-the-box luminus template?
01:34bitemyappbill610: it depends, but Luminus should be reloading for you.
01:35bitemyappbill610: you need to understand that the handler is one big rolled up "value" of composed functions into a single function.
01:35bitemyappbill610: that blob value doesn't get reloaded unless again, you add the indirection of a var
01:35bitemyappthen you're just pointing to a nominative place to *get* the value
01:36bitemyappbill610: but yeah, Luminus should be doing this for you, unless you did something weird.
01:36bitemyappyogthos: ^^ ahem
01:37bill610bitemyapp: I *tried* not to do anything weird
01:46justin_smithbitemyapp: wrap-request was a relic that was no longer used, just got deleted, thanks for catching that
01:47muhoois there a way to add my clojars username to my profiles.clj so it stops asking me for it all the time?
01:47coventryI'm releasing some very simple emacs integration with clojure.tools.trace. If anyone has time to smoke-test the README at https://github.com/coventry/troncle I'd be grateful for any feedback.
01:49coventrymuhoo: Yes, e.g. :auth {:repository-auth {:username "coventry" :password "XXX"}} in :user
01:50coventrymuhoo: there's a way to do it with an encrypted file, too, described at https://github.com/technomancy/leiningen/blob/master/doc/DEPLOY.md#authentication but I haven't gotten that working yet.
01:50muhoocoventry: really? :auth is not documented in sample-profile.clj
01:50muhoosorry, sample.project.clj from leiningen
01:50coventrymuhoo: It's working for me. Probably not recommended because it's insecure.
01:51muhooi don't need the password in a file. just the username
01:51muhooi'm concerned that it's not mentioned at all in the docs afaict
01:51coventryI'm not an expert and could be wrong. I only just got this together this evening.
01:54coventryActually, I'm probably wrong. "lein deploy" keeps hitting gpg-agent, so I guess it must be accessing the credentials.clj.gpg I created, even though I have no configuration specifying that.
01:56eggheadhuh, my core.async program just keeps exiting without doing any work :/
01:56muhoocoventry: troncle looks interesting. i've been annoyed by having to type (comment (require 'clojure.tools.trace) (clojure.tools.trace/trace-vars sometihng.i.need.to/trace))
01:56muhooand then untrace-vars it when done
01:56bitemyappjustin_smith: np
01:57coventrymuhoo: Actually, nrepl-discover has that functionality already. (M-x nrepl-toggle-trace after running M-x nrepl-discover.)
01:58nid1Hey folks. Is anyone in here using the https://github.com/stuarth/clj-oauth2 library? We're having a bit of trouble with the code which checks if the request is on the callback url… it seems like it will unavoidably throw an exception, but perhaps we're misunderstanding how it's supposed to be used (the documentation is wrong/ambiguous in a few places, so we might be putting too much faith in that as well).
01:58muhoocoventry: really? i thought that was only in cider?
01:59nid1@stuarth's fork is one of many, so we'd love to talk to anyone else who's using clj-oauth2 from any source. :)
01:59bitemyappmuhoo: dude, I use a macro for that.
01:59coventrymuhoo: Nope, it's working for me with standard nrepl. Didn't know nrepl-discover was going in cider.
01:59muhoocoventry: also i have to insteall nrepl-discover
01:59bitemyappmuhoo: "c-c c t r o" and c-c c t r f
01:59bitemyapp"Trace On" and "Trace oFf"
01:59muhoooff i go to marmalade then
02:00muhoosure enough, nrepl-discover. will try
02:00coventrymuhoo: The nrepl-discover on marmalade doesn't work with troncle, FWIW.
02:00coventrymuhoo: Note that the nrepl-discover.el package requires you to get nrepl.discover into your jvm first.
02:00coventry(See the first few lines of troncle.el)
02:09eggheadre: core.async -- am I doing something wrong here? https://www.refheap.com/20795
02:09eggheadI just want to have a lil' async pipeline and drain it until the lazy-seq is exhausted
02:10echo-areaMust method names of a protocol be strictly confirmed to Java specifications, if such a protocol is supposed to be used with `proxy'?
02:11echo-areaI tried, and UnsupportedOperationException was thrown if I didn't name them that way.
02:11eggheadif you implement an interface... :p
02:11echo-areaE.g. names like `get-v' won't work, but names like `get_v' will
02:12eggheadya echo-area in the same way that if you make a clojure protocol you can't use get_v where the protocol expects get-v
02:12echo-areaAlthough in both cases the proxy object declares a .get_v method
02:12echo-area*declare
02:14amalloyecho-area: name munge-ing to and from java is a rather wonky topic, and i wouldn't be surprised to hear that something as old as proxy has issues with it
02:14echo-areaIs proxy very old?
02:15amalloyit predates protocols, reify, and deftype by a long way
02:15amalloyif you're defining a protocol, i can't imagine a reason to proxy it rather than reify it
02:16echo-areaIt's not a real program. I'm constructing a small program to understand another behavior I'm confused with
02:16echo-areaI just didn't want to write a .clj file and a .java file for this program
02:17echo-areaI should have said "a program for real use"
02:18amalloystill, why proxy? any use of proxy should be looked at with great skepticism; and if this is just a toy project i don't expect you need it
02:19echo-areaThe feature I'm experimenting with is something involving proxy, in a real project where a Java interface is used.
02:20echo-areaI need simplified code
02:21amalloyjava interfaces should be reified too, not proxied
02:21amalloythe only excuse for proxy is if you need to extend a concrete class
02:21echo-areaHmm, are you saying that proxies are deprecated?
02:21echo-areaFor most cases?
02:21amalloyyes
02:22amalloyi mean, i'm sure rich hasn't officially used a DEPRECATED rubber stamp
02:22muhooegghead: " I just want to have a lil' async pipeline and drain it until the lazy-seq is exhausted" now there's a song lyric
02:22amalloybut you should always use reify instead
02:22amalloyonly if reify is impossible should you consider proxy
02:26muhoothe nmemonic i've used is: proxy means "extends", reify means "implements" and gen-class means "i really wish i didn't have to deal with java so much"
02:26eggheadmuhoo: I still haven't gotten it to work :(
02:26Guest73040muhoo: thanks. that clears things up.
02:27muhooegghead: sorry, i know a lot more about song lyrics than i do about core.async
02:28echo-areaamalloy: I see. But I'll finish my experiment anyway, as it will teach me another thing I'm confused with :)
02:31amalloysensible
02:35andyfingerhutChas Emerick's flowchart from his book is available on-line and seems helpful for choosing between several Clojure choices: https://github.com/cemerick/clojure-type-selection-flowchart
02:38sm0kein postal how do i send mail by a particular name?
02:39sm0kehmm i should try "Someone <someone@mail.com>"
03:03sm0kehow do i destructure a function argument if its a map with string keys like {"a" 1} for funciton like (defn f [{:keys [a]}])
03:03sm0ke{:a 1} works fine
03:06opqdonut,(let [f (fn [{a "a"}] a)] (f {"a" 1 :a 2}))
03:06clojurebot1
03:06opqdonutsm0ke: ^
03:06eggheadhmm, the current release of core.async seems a bit broken
03:06opqdonut:keys only works for keyword args
03:06opqdonuterr, keyword keys
03:07eggheadputting a range into a channel and getting less than the range out... :/
03:08eggheadmebbe it just a bug in my code tho
03:09sm0keopqdonut: thanks
03:19eggheadshouldn't this core.async program write out 100 lines to output.txt? https://gist.github.com/eggsby/7445491
03:37jballancopqdonut: use :strs
03:37jballanc,(defn foo [{:strs [a]}] (println a)) (foo {"a" "Hello"})
03:37clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
03:37jballancbah
03:38jballancwell...like that
03:39jballanc,(letfn [(foo [{:strs [a]}] (println a))] (foo {"a" "Hello" :a "Goodbye"}))
03:39clojurebotHello\n
03:40jballancthere we go
03:42sm0kenice
03:45sm0keif my map has a key :type and i do [{:keys [type]}] how does it works
03:45sm0kedoes type resolves to core/type ?
03:45sm0kehow do i fix that
03:47logic_proggiven the existence of core.async, is there still any need for clj-kilim ?
03:49opqdonutoh, :strs is just not documented
03:49opqdonutoh, no it is, I just can't read
03:57jballanc:)
04:28Fraz1morning all
04:29Fraz1I am having some trouble with my leiningen which I hoped someone could help me debug
04:29Fraz1I do this in one tab
04:29Fraz1lein repl :headless :port 2888
04:29Fraz1then in another tab
04:29amalloysm0ke: it's important to understand that :keys, :strs, and :syms are all just short hand for the general map-destructuring syntax
04:29Fraz1lein repl :connect 2888
04:30Fraz1(require '[clojure.tools.namespace.repl :refer :all])
04:30Fraz1(refresh)
04:30Fraz1then I disconnect the repl session with ctrl+d
04:30Fraz1and re-issue the connect command
04:30Fraz1lein repl :connect 2888
04:30amalloyeg, if you have the map {[:age 20] 1}, you can destructure it with (let [{twenty-year-olds [:age 20]} m] ...)
04:30Fraz1at this point I see errors
04:31Fraz1CompilerException java.lang.RuntimeException: Unable to resolve symbol: defmacro in this context, compiling:(NO_SOURCE_PATH:1:5)
04:31Fraz1I realise this is most likely due to a bug in the code (mine) loaded by (refresh)
04:31Fraz1but is there any way for me to get context about what the error actually is?
04:57muhoooh am i going to have some fun tomorrow with peridot
05:00llasramAt the Conj?
05:04muhoono, on my own here
05:05llasramAh
05:05muhooif i were at the conj i'd be having fun watchign talks
05:05llasramWell, enjoy the peace and quiet in the channel :-)
05:07clgvthe conference attendees seem to often hang around here during the breaks, though ;)
05:12jeDoes it make sense to use core.async (timeout) to insert a pause between polling a webservice?
05:15WWWestHi all!
05:16WWWestI'm trying to workaround using the final method on nodejs' crypto stuff. when cljs sends the code to closure, it will fail because final is a reserved key word in ES 3
05:18WWWestI tried something like this ((aget crypto "final") crypto), but I get "cannot call method final of undefined"
05:18WWWesthow can I execute the result of the aget on the crypto object?
05:20Apage43maybe.. (.apply (aget crypt "final") crypto)
05:20Apage43rather (.apply (aget crypto "final") crypto)
05:21Apage43(need to use apply as crypto needs to be bound to 'this' for the call)
05:23WWWesthaha! .apply worked
05:24WWWestthanks!
05:33sm0kehey guys i have this really annoygin problem with ring request
05:33sm0kei can see :body #<BytesInputStream BytesInputStream[len=5]> in my req map
05:33sm0kebut when i do (slurp (:body req)) i get nothing
05:35sm0kei am using curl -XPOST "localhost:9000/service" -d "12345"
05:36Apage43sm0ke: you don't have other middleware that might be reading it before you do you?
05:36sm0keno i just have (run-server (handler/site #'routes) {:port server-port})
05:37Apage43sm0ke: hm. And if you put a (.reset (:body req)) just before the slurp its still empty?
05:37sm0kelet me try
05:38sm0keApage43: it works
05:38sm0kewhats that?
05:38Apage43handler/site is from compojure?
05:38sm0keyes
05:38Apage43that adds several middleware, one of which is probably reading your body
05:39sm0kehmm weird
05:39Apage43https://github.com/weavejester/compojure/blob/master/src/compojure/handler.clj#L28-L38
05:39sm0kebut i have been using the same code since some time
05:39sm0kenever faced this before
05:39Apage43probably wrap-multipart-params
05:40sm0keand yes i am using http-kit
05:41Apage43inputstreams are stateful and have an internal position
05:41Apage43some of them actually *can't* be rewound, so it's tricky
05:42sm0kebut i still dont get what makes my code behave like so
05:42sm0kei have no extra middleware
05:43Apage43yeah, multipart-params shouldn't touch the body unless the content type is set to multipart/form-data
05:43Apage43hmm
05:44Apage43sm0ke: what if you just (run-server #'routes) ...
05:44Apage43(without wrapping in handler/site)
05:45Apage43if that works it indicates that http-kit hands the thing to you already seeked to the end
05:45sm0keyeah that works
05:45Apage43okay, if that works then it must be one of the middleware that handler/site attaches
05:46sm0kethis is sad
05:47Apage43sm0ke: paste the whole request map on refheap?
05:48sm0kewith site middleware?
05:49Apage43yeah
05:49Apage43i mean
05:49Apage43the request map as printed should be the same with or without
05:49Apage43well.. the original part
05:49Apage43the middleware will do param decoding and stuff
05:50Apage43but yeah, post middleware processing
05:54sm0keok this took me forever
05:54Apage43another thing might be handy
05:54sm0kejust couldnt get formatting right https://www.refheap.com/20804
05:55Apage43(proxy [java.io.ByteArrayInputStream] [(byte-array [])] (read [& _] (throw (ex-info "Somebody read me!" {})))) ;; this returns an input stream that will throw an exception if anything reads it
05:55Apage43you could try taking your captured request, but associng that as :body
05:55Apage43and seeing where the exception gets thrown from
05:56Apage43sm0ke: got it
05:56Apage43the params middleware sees the content-type set to application/x-www-form-urlencoded and tries to read params out of the body
05:57Apage43try adding -H 'Content-Type: text/plain' to your curl
05:58Apage43or application/octet-stream
05:58sm0keHow on earth did you figure that out?
05:58Apage43reading the ring source and educated guessing; https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/params.clj#L22
05:58sm0kethis seems to explain everything on why it was working before
05:59sm0kebefore i was testing from browser with jquery and its seems to set text/plain
05:59sm0keApage43: kudos
05:59Apage43sure :)
06:00Apage43sm0ke: if you have a special type of data for your application, perhaps come up with a content-type for it
06:01sm0keyeah makes sense
06:01Apage43that way you can be sure other middleware doesn't fire
06:02Apage43inputstreams are one of those unfortunately side-effectful things :/
06:41tickingTuim: telling everybody an artificially pricey part (the hiwin rails) so that you gain market advantage kinda looses my trust, he could at least explicitly said (part I use withheld)
06:41tickingwhops sorry, I
06:42tickingdisconnected and my client changed the channel :(
07:22jeAny thoughts on how I can poll a http resource wihtout having the wait times between the polls consume an entire thread (polling multiple things): ask http for result, if result final return it, else wait and ask again
07:27astevehow do you guys debug running clojure processes?
07:27CookedGryphonje: http-kit allows you to do asynchronous requests with a callback
07:28CookedGryphonje: and then if you want to wait for several in a single thread perhaps core.async and an alts! statement
07:29jeCookedGryphon: I don't think I'm interested in a callback... I get the answer fairly fast, its the wait time in between
07:30jeCookedGryphon: I've looked a core.async for a few hours now (go blocks is totally new to me), I can't seem to bend it to my needs :)
07:30CookedGryphonI know what you mean, I haven't quite got around to it yet myself, but my colleague did a thing with it which is almost exactly what you describe
07:31CookedGryphonhe's pulling multiple web pages which might take indeterminate amounts of time
07:31CookedGryphonset up http-kit with a callback which puts the result into a channel
07:31CookedGryphonand then does alts on the resultant channels so whatever comes back first gets dealt with and nothing blocks
07:37pyrhi
07:37pyrI'm trying to implement a class that "extends" another from java lang, and which requires the "Local" annotation
07:37pyrin java the classes look like:
07:38pyr@Local(value=Something.class)
07:38pyrclass SomethingElse extends Something { ...
07:38pyr(I hate myself for having to do that, but oh-well)
07:39CookedGryphonis there any reason you can't just do it in java and call into clojure/use the resulting class directly
07:39pyrnope
07:40CookedGryphonI find that's usually less headache when dealing with naff java stuff - otherwise you just end up with ugly clojure anyway
07:40pyrmakes sense
07:40pyrwhy it isn't an interface in the first place is what beats me, but I can't work around that
07:41CookedGryphonIf you're working with beans, I don't know if there's anything in clojure/java.data which might be useful to you
07:42nDuffpyr: adding annotations means you need to use gen-class
07:42pyrnDuff: yup, already the case
07:44nDuffpyr: can you show what you're doing now?
07:44pyrnDuff: I currently have (:gen-class :name ^{Local {Value Superclass.class}} Subclass :prefix foo- :methods [...])
07:44pyrnDuff: I tried several variations on the the metadata for adding the "Local" annotation
07:45pyrbut the java app that loads the class consistently fails with Unable to find Local annotation for class
07:45jeCookedGryphon: I will take another swing at it :)
07:46nDuffpyr: what you gave there doesn't look right to me, but I'm trying to find my own code that uses annotations right now.
07:46pyrnDuff: I took hints from: https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/genclass/examples.clj
07:47nDuffpyr: when I've done it successfully, I didn't attach the annotation info to the :gen-class in my ns macro.
07:47pyrnDuff: where then ?
07:47nDuffpyr: ...but rather did it as part of an explicit (gen-class) form later.
07:47pyrah
07:51pyr\o/
07:51pyrturns out it was the path to Local which was wrong
07:51pyrthanks for the pointers
08:16gunsGood morning. In CLJS, is (:refer-clojure :only […]) always preferred over (:require [cljs.core :refer […])?
08:16gunsIt seems to me that cljs.core is mostly an implementation detail
08:30wakeuphi
08:31wakeupcan I work my way around a cyclic dependency?
08:31mdrogaliswakeup: Namespaces or functions?
08:31wakeupnamespaces
08:32wakeupI just thought of using :only
08:32wakeuptrying that now
08:32mdrogalisYou're definitely going to want to regroup.
08:33wakeupwhat do you mean by regroup?
08:33mdrogalisReorganize your functions to break the cyclicness.
08:33wakeuphmm :only doesn't do it.
08:33wakeupthe functions arent cyclic
08:33wakeupjust the namespaces
08:34wakeupI have two categories of functions, some of the use each other but
08:34wakeupthat's it.
08:34mdrogalisRight, but I mean, you're going to need to shuffle the location of the functions around.
08:34gunswakeup: extract the common set of functionality from namespaces 'a and 'b into a third ns 'c
08:34wakeuphmm
08:34wakeupguns: good point.
08:35gunsclojure is more restrictive on this point than many other langs, but it helps avoid making spaghetti
09:15bfarahleave
09:19dnolenguns: the first one is only for core since everything is implicitly referred. The :require is for everything else.
09:19gunsdnolen: So users should never explicitly require from cljs.core?
09:20dnolenguns: everything is implicitly referred, there's no point
09:20gunsor rather, exclude
09:20gunssorry
09:21gunse.g. (:refer-clojure :exclude [defn]) is always preferred over (:use [cljs.core :exclude [defn]))
09:29pyrstill on the interop side of things, lets say i have a class that extends another (which I successfully built with the correct annotations with gen-class)
09:29pyris there a way to call super.something from the clj code ?
09:30dnolenguns: the second one is not valid in CLJS
09:31gunsdnolen: ty; this is in the context of slamhound and ns-form rewriting. (:require [cljs.core …]) was being produced as a consequence of the algorithm
09:32dnolenguns: slamhound probably doesn't support CLJS
09:32gunsdnolen: yes, but it finds vars in cljs.core if it exists on the classpath
09:32dnolenguns: sure but I wouldn't use slamhound w/ CLJS period
09:34mdrogalisJust remembered the pseudonym Leon Repl. What a terrific alias.
09:36gunsdnolen: yes, I agree. My question didn't make much sense from the perspective of a CLJS user
09:43tufflaxI have a design (code) problem. Please take a look if you have the time: https://www.refheap.com/20811
09:45mdrogalisHeya tufflax. I worked on two things that might be of interest to you..
09:45justin_smithtufflax: one thing to consider: break game state into instances / rooms so that most updates only matter to others in the same instance and the same "room" (which can be an arbitrary radius in open space)
09:46mdrogalisI tried a small scale MMO last spring. I got bored, but there's a few ideas you can pilfer. https://github.com/MichaelDrogalis/maple
09:47justin_smith mdrogalis: would that be an morpg, or maybe just orpg?
09:47mdrogalisjustin_smith is right though, that advice is sound
09:47mdrogalis.. I guess it would in fact be an orpg :P
09:47justin_smithmy first "coding job" was volunteering as a C coder for a foss mud
09:48tufflaxjustin_smith yes but still, sending changes is the most efficient, and the problem is still there
09:49justin_smithtrue - don't think about functions with output types, think about streams with polymorphic messages, and subscribers that can handle each kind of message in the right way
09:49justin_smithie. (:event actor target {...})
09:50justin_smithso it starts with a keyword used for dispatch, gets sent on a go channel
09:50justin_smithor over a websocket
09:50tufflaxthat is kind of what I was talking about with the queue idea, is it not?
09:50justin_smithdispatch as in what it does (which determines args) not target
09:50tufflaxor similar to it
09:51justin_smithyeah, async go blocks are a nice way to do queues
09:53justin_smithif you break up state into "near" state, "region" state, and "map" state, a vast majority of data only needs to be shared with others in the same "near" state, a smaller amount (like shouts or big explosions) need to be shared in a "region", and nearly nothing (global chat? auctions?) needs to be distributed globally
09:54justin_smithso your mmorpg with thousands of players, is really hundreds of 10 player games
09:54justin_smiththat can enter and exit one another :)
09:55tufflaxAre you suggesting that then I just send the whole state for every little room? That's can still be like 10 times more data than just updates.
09:55justin_smithno, that just helps state be more managable
09:55justin_smithif you narrow scope
09:56justin_smithfull resend of state on big ticks, updates on little ticks
09:56justin_smithalso send state when transitioning between region
09:57justin_smithbig ticks and little ticks being async regular callbacks (think seconds and minutes, but on a smaller scale) that propagate synchronization and trigger automated mob events etc.
09:57tufflaxYes, yes, but what about generating events/deciding what to send (deciding what has been updated)? That is my problenm
09:57tufflaxmdrogalis: I'll take a look btw
09:57tufflaxthanks
09:57justin_smithevery actor (mob or player) publishes actions, and is implictly subscribed to the room they are in
09:58CookedGryphontufflax: I'm writing a game at the moment, and I've found this talk really really useful: http://www.youtube.com/watch?v=V1Eu9vZaDYw
09:58tufflaxCookedGryphon: thanks ill take a look
09:59CookedGryphonnicely separates behaviour from state from the code to actually do stuff and observe
09:59justin_smithyes
09:59CookedGryphonthen in terms of implementation i've been playing with ova (ref to a list of refs with nice selectors)
10:00CookedGryphonand something i like the look of but haven't yet played with is http://blog.paralleluniverse.co/post/44146699200/spaceships
10:00CookedGryphonwhich is a spacial database specifically designed for large simulations
10:00tufflaxjustin_smith: Ideally I would like this oracle that can just look at the game state and decide what has been updated, or something that would require me to care about publishing actions/generating events just as little as if I had the oracle
10:00tufflaxYp
10:00CookedGryphonwhich lets you quickly query based on distance and areas
10:00tufflax:p
10:01justin_smithtufflax: why not qualify actions in terms of how wide their consequence scope is, and just send to everyone who subscribes to that scope
10:02justin_smithso your internal concept of state, and each client, are parallel subscribers
10:02justin_smithuntil, of course, someone switches context by entering/leaving a room, then they get a full push
10:03CookedGryphonif you have the component entity system and this spacial database, you can subscribe/request all the entities in a given space and have some mapping over the entities if you want to filter out secret internal state
10:03CookedGryphonshould be fairly trivial
10:03tufflaxjustin_smith: the problem is not about who gets it, the problem is to not have to be explicit about these updates at all
10:03CookedGryphonseperate out observing the state from changing it
10:03justin_smithtufflax: just declare a subscription and let each actor publish
10:03justin_smithit is mostly implicit
10:04justin_smithie. you don't loop over subscribers, let core.async do that
10:04justin_smithjust declare who is listening
10:04tufflaxyeah maybe. I'll think about it, and look at CookedGryphon and mdrogalis stuff too
10:04tufflaxthank you
10:06mdrogalisGood luck & have fun, tufflax :)
10:07tufflaxthanks ;)
10:07justin_smithyeah, good luck and have fun
10:07justin_smithif you are lucky, you may even have to worry about griefers and people exploiting bugs in your code
10:08justin_smiththat's when you know you've succeeded - people actually care :)
10:08tufflaxhehe yeah
10:08tufflaxCookedGryphon: I think I have seen this. He talks about how he did not use persistent data structures in his code, right?
10:09CookedGryphondon't remember that
10:09mdrogalisI've taken to the advice of Richard Feynman. Always have some piece of work that you're just playing with and not trying to make money off of.
10:09tufflaxhehe
10:09CookedGryphoni took what he said about keeping all the state and behavioural definitions as data with systems acting on them
10:09CookedGryphonand probably did my own interpretation
10:10CookedGryphonbut i've found it to be really powerful
10:10CookedGryphonallowing me to do things like add features while people are playing :P
10:10CookedGryphonwhich always gives an awesome "how teh hell did you just do that" moment
10:10tufflaxhehe ok ill watch this anyway ;)
10:10CookedGryphonespecially if the people aren't used to clojure at all
10:10tufflaxhehe
10:11CookedGryphonit also makes it ridiculously easy to test features in isolation
10:11CookedGryphonbecause you don't have to build actors and interactions between them
10:11CookedGryphonyou just have the elements you need of the entity before and after
10:11CookedGryphonand as long as you don't clash namespaces, you're golden
10:13llasram /Clash of the Namespaces/ would make a good title for something
10:14justin_smithrelaease the Garbage Collector!
10:14justin_smithmuch scarier than a little kraken
10:18CookedGryphonis there a HOF which would do the same as (reduce (fn [acc f] (f acc)) coll) ?
10:18CookedGryphoni have a vector of ring middlewares that I want to make into the appropriate function
10:19justin_smith((apply comp fn-collection) initial)
10:19justin_smith?
10:19justin_smithyou may need to reverse the fn-collection
10:20onthestairsam i right in thinking there is a function f in clojure.core such that (f g x) = [x g(x) g(g(x)) g(g(g(x))) ...]?
10:20onthestairscant think of the name of it
10:20justin_smithonthestairs: iterate
10:20onthestairsjustin_smith: thanks
10:21justin_smith,((apply comp [float inc inc inc]) 1)
10:21clojurebot4.0
10:23CookedGryphonhmm
10:23justin_smithcomp is like -> except of course not a macro, and opposite argument order
10:23CookedGryphonyeah, just wondering which is more evident
10:23justin_smithso if any of the middleware take multiple args, you need to make a lambda to put the prev result in the right position
10:24mklappstuhlis this still ‘the thing’ to have some simple math stuff in clojure: https://github.com/clojure/math.numeric-tower
10:24mklappstuhl?
10:24justin_smithI usually just use -> to build my middleware, but maybe you have an advantage to having them in a sequence
10:25justin_smithmklappstuhl: there is also jvm interop if you are OK with jvm native types
10:25justin_smith,(Math/pow 2.0 (/ 1.0 12.0))
10:25clojurebot1.0594630943592953
10:25justin_smiththe ratio from one note on a piano to the next
10:26mklappstuhljustin_smith: know about that but I want to show someone else how to do some simple stochastics in a programming language so that'd be just additional complexity
10:27CookedGryphonjustin_smith: so my concept is, to build up a middleware stack much like a multimethod
10:27justin_smithif your concern is idiomatic clojure semantics more than the performance you would get from native types, yeah, go with numeric-tower I think
10:27justin_smithCookedGryphon: as in different requests would get different middlewares?
10:28CookedGryphonnope, that would just be a multimethod
10:28CookedGryphonas in different namespaces can add in their own stages
10:28justin_smithahh
10:28CookedGryphonwith dependencies on others to establish the order
10:28mklappstuhljustin_smith: it's super simple stuff so perf is not a concern :)
10:28justin_smithso the definition would be spread
10:28CookedGryphonyeah, rather than having one god namespace that has to know about all the things that will get added in
10:29CookedGryphonand also to be able to add in debugging, remove things at runtime
10:30justin_smithCookedGryphon: for that I use a "when-staging" function, takes a middleware as an argument - if environment is :staging it acts like that middleware, if environment is not :staging it is a noop middleware
10:30justin_smithyou could also make that a macro of course
10:31CookedGryphonyeah, that was a bad example
10:31justin_smithI use this for things like verbose profiling, or controlling reload
10:31CookedGryphonreally i want to avoid unecessary namespace dependencies
10:32CookedGryphonbecause as long as you're strict and enforce only adding namespaced keywords, there's no risk of getting into a mess allowing other namespaces to tweak the map on its way through
10:32justin_smithI am very fond of middleware as a design because it simplifies the composition of functionality of libraries
10:33justin_smithmy worry as I hear you describe this is that it would reduce some namespace complexity by adding complexity to the middleware model
10:33CookedGryphonthe only complexity it's going to add is the order dependency
10:33CookedGryphonwhich is currently something you do manually
10:34CookedGryphonand quite often have to think hard about and examine what your middlewares are doing
10:34justin_smithright
10:34CookedGryphonand waht needs what information
10:34justin_smithI should shower and leave for work, be back later
10:34justin_smithbut interested in what you are doing here
10:34CookedGryphonwell if it works nicely i'll no doubt make a little library
10:35jcromartiewhat's the difference between a class with a single method and a closure?
10:35jcromartie(rhetorical question)
10:47TimMcjcromartie: Objects are the poor man's closure; closures are the poor man's object.
10:51tbaldridgejcromartie: well, if you build closures the wrong way (like Python), with mutable closed over values, then there really isn't much of a difference.
10:53jcromartiewell, let
10:54jcromartiewell let's say you properly separate the concept of state and value :)
10:54TimMcObjects can be final.
10:54tbaldridgeso the difference between closures and deftype. There really isn't much of a difference, imo.
10:55TimMcEither way, you're bundling up some context with a function.
10:55TimMcand you can bundle that function with different values if you want to.
10:56TimMcI could create a "biclosure" that has two invocation points and it would look like an object with two methods.
10:56jcromartieI was just working with a library in an ostensibly OO language, where there were lots of classes like that. They only served to define an interface for a single method over some state. Kingdom of Nouns, you know...
10:56jcromartieTimMc: two invocation points?
10:56TimMcYes, those are closures.
10:57TimMclike .invokeA and invokeB
10:57TimMcIt would be weird. :-)
10:58jcromartiegoogling "biclosure" yields lots of extremely dense math papers
10:58TimMcI made it up just now.
10:58mdrogalisGenius.
10:59TimMcImagine if you could write (fn (invokeA [x] (+ x 4)) (invokeB [x y] (* x y))) and then call it like (foo 6) or [foo 7 8] to invoke one endpoint or the other.
11:00TimMc(If you really wanted that in Clojure, you'd just use different arities or have a dispatch argument.)
11:00jcromartieyeah
11:01TimMcSo java.lang.Integer is like a closure with a distinguished dispatch argument (the method name).
11:01jcromartieyou can actually define multiple arities for anonymous fns
11:02jcromartie#(((fn ([x] x) ([x y] (+ x y))) 1)
11:02jcromartieI mean
11:02jcromartie,((fn ([x] x) ([x y] (+ x y))) 1)
11:02clojurebot1
11:02jcromartie,((fn ([x] x) ([x y] (+ x y))) 1 2)
11:02clojurebot3
11:02TimMcInstead of calling (5 :compareTo 6) you say (.compareTo 5 6)
11:08jcromartieimmediately-invoked self-referential multi-arity anonymous functions have great potential for obfuscation
11:09jcromartiebut you can't recur with different arity :| so it's impossible
11:09jcromartieaw
11:10AimHereCan't you fake a multi-arity recur though?
11:11AimHereHave a macro that wraps all the arguments in a data structure and then unpacks them as requred
11:14pyrre: interop jungle
11:15pyrI was able to create everything I needed from clojure, except a small thing
11:16pyrThe class I need to build extends on a previous one and in one of its methods does: ComponentLocator.getLocator(SomeClass.name)
11:16S11001001,(doall 1)
11:16clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
11:16pyrI can't see to find that "name" property in clojure
11:17TimMc,(doall "hello")
11:17clojurebot"hello"
11:18TimMcpyr: Is that a static field?
11:18pyrTimMc: nope (as in SomeClass/name)
11:19pyrto be honest there is so much DI hell in this project, I have no idea where it comes from :)
11:21jcromartiepyr: why can't you just use (.name x) and not worry about it? or is the reflection penalty too big in this case?
11:24pyrjcromartie: cause it doesn't work
11:25pyrjcromartie: https://github.com/apache/cloudstack/blob/4.0.2/plugins/user-authenticators/md5/src/com/cloud/server/auth/MD5UserAuthenticator.java#L86
11:25pyrthat's the code in java
11:25pyrin clj, i can't access that property
11:26pyrweird
11:26TimMcpyr: case
11:26TimMcOr is that a subclass?
11:26pyrTimMc: case ?
11:26nDuffpyr: what are the maven coordinates to get that dependency?
11:26TimMcManagementServer$Name or (.Name ManagementServer)
11:27TimMcpyr: Name, not name
11:27pyrah
11:27llasramI was going to say, looks like an inner class
11:27muhooManagementServer$Name ?
11:27nDuffmuhoo: that's the syntax for referring to inner clrasses
11:27pyrnDuff: there are none
11:27pyrnDuff: has to be locally built in maven
11:28TimMcnDuff: Or rather, the way the Java compiler fakes inner classes.
11:28nDuff*nod*.
11:29muhoofwiw, i use this tool (org.timmc.handy.repl/show SomeWeirdJavaThingWTF {:inherit :true} )
11:29muhooto see what's really going on.
11:29muhoowhen dealing with crazy java stuff
11:29nDuffmuhoo: ...oooh, nice.
11:30muhooi should make an nrepl plugin for it
11:31muhooor, somene who knows more about nrepl should.
11:31pyrin 3.5 years of clojure i hadn't done that much interop: now i know why :)
11:31pyrwell, can't find a way to call it, too bd
11:31pyrbad
11:32TimMcpyr: Can you find ManagementServer.java?
11:32nDuffpyr: I'd be very, _very_ surprised if it can't be done.
11:32justin_smiththis may be obvious, but clojure.reflect helps with this stuff too
11:32nDuffpyr: ...and if you're at the point of giving up, I'd be happy to take a shot at it. If there aren't published binaries for that code, where would I find the source?
11:33pyrTimMc: it is there https://github.com/apache/cloudstack/blob/4.0.2/server/src/com/cloud/server/ManagementServer.java
11:33pyrnDuff: it's a monster
11:33jcromartiepyr: ComponentLocator.getLocator(ManagementServer.Name);
11:33pyrnDuff: https://github.com/apache/cloudstack (against tag 4.0.2)
11:33jcromartiepyr: in Clojure would be (.getLocator ComponentLocator ManagementServer/Name)
11:34seangroveI think I can actually go.
11:34pyrjcromartie: except this doesn't compile, ManagementServer/Name is not a static field
11:34muhoojustin_smith: i'm pretty sure that the timmc.handy.repl stuff is mostly nice formatting around clojure.reflect
11:35pyrTimMc: https://github.com/apache/cloudstack/blob/4.0.2/api/src/com/cloud/server/ManagementService.java
11:35pyrTimMc: looks like Name comes from here
11:35justin_smithmuhoo: so its more about display, where clojure.reflect just gives you datastructures?
11:35muhoojustin_smith: i vaguely remember that, it's been a while since i looked at the code for it.
11:36jcromartiehm, that's tricky huh
11:36justin_smith"static final String Name"
11:36muhoostatic? ManagementServer/Name then ?
11:36nDuffpyr: use ManagementService/Name rather than ManagementServer/Name
11:36pyryup will do that
11:37pyrnDuff: build on 4.0.2 needs to bypass awsapi
11:37justin_smithpyr - this may help http://stackoverflow.com/questions/850148/accessing-java-static-final-ivar-value-through-reflection
11:37justin_smithor it may not
11:38pyrone last thing, is there anyway from clj to call super (outside of proxies, which have proxy-super)
11:38justin_smithpyr: have you seen this? http://stackoverflow.com/questions/2572312/how-do-i-pull-static-final-constants-from-a-java-class-into-a-clojure-namespac
11:38jcromartiepyr: where would you call super other than a proxy?
11:39mdrogalisseangrove: Where/when is it this year?
11:39pyrjcromartie: in a class that extends another
11:39pyrjcromartie: class Foo extends Bar
11:40pyrjust out of curiosity, I've seen java code do that, fortunately i don't need to in my extensions
11:40jcromartiepyr: I'm afraid the question doesn't really make sense. The only way to declare a subclass in Clojure is with `proxy'.
11:40muhoojcromartie: or genclass, i think, too?
11:40pyrjcromartie: nope (:gen-class :name Foo :extends Bar)
11:41jcromartieah, yes
11:41pyrjcromartie: which is what I have to go through to build my extension for cloudstack, since they didn't seem to think interfaces would be a good idea...
11:41pyrcloudstack is a really great example of a project that would be an order of magnitude simpler & smaller in clj
11:41justin_smith"gen-class will actually override and implement all interface and superclass methods by default with implementations that try to forward to specially named functions in your generated class (if they exist). These functions are named with the method name and types of their args." http://tech.puredanger.com/2011/08/12/subclassing-in-clojure/
11:42jcromartiehttp://stackoverflow.com/questions/9060127/how-to-invoke-superclass-method-in-a-clojure-gen-class-method
11:42jcromartieso you need to alias the superclass methods
11:42jcromartieinteresting
11:42pyrah, fun
11:42jcromartiesorry :) I've only ever had to create subclasses using proxy because most APIs expect you to pass them an object, rather than specify an AOT-compiled class :)
11:43justin_smithjcromartie: my link claims that they are implemented by default (have not tried it myself)
11:43llasramWhen you start needing to do that sort of thing, I usually find it's easier to implement a tiny stub Java class which calls into Clojure for the actual implementations
11:43pyrjcromartie: np, today was a fun expirement
11:43pyrjcromartie: I would'nt spend my days in interop land though
11:43pyrjcromartie: I'm much more comfortable sticking to clojure
11:43llasramThe way I see it, Java is a pretty reasonable DSL for implementing Java classes
11:43pyrapache cassandra has a much nicer design
11:44pyrit relies on interfaces for extensions so you can just deftype away
11:44jcromartiejustin_smith: they are overridden by default
11:44pyrllasram: agreed, but who doesn't like a challenge
11:46pyrthanks a lot for the hand-holding guys !
11:46pyrand sorry about being brain-dead about these issues
11:46pyrs,about,for
11:59seangrovemdrogalis: Not sure, I assume similar time as last year
12:00seangroveSo, March-ish 2014?
12:00mdrogalisAh, nice
12:00TimMcjustin_smith, muhoo: o.t.h.repl/show is actually a display wrapper around ot.h.reflect -- I was fed up with clojure.reflect for some reason.
12:02sritchieif any friend users are around,
12:02sritchiedo you guys have any good recs for granting route-based permissions?
12:17justin_smithsritchie: shot in the dark - give a sub-path and children needing separate auth their own handler / workflow? I am still looking at friend but have not integrated it yet
12:19sritchiejustin_smith: I'm thinking of, say, authenticating a post's author
12:19sritchieyou're an ::author, but only of this blog or post
12:22rurumate,(.indexOf [1 2] 2)
12:22clojurebot1
12:22rurumatehow to do that in clojurescript?
12:22justin_smithsritchie: what about creating a map like {::author [article1 article5] ::admin [page-X]} when the auth happens?
12:23justin_smiththen attaching map to session, and checking that
12:23sritchiejustin_smith: friend will only accept either a set of roles or a func that returns a set of roles -
12:24sritchieso I could check a dynamically bound session, I guess
12:25justin_smithsritchie: typically I have a permission table in the db, each has a role and a model, and each user has a set of permissions
12:26justin_smithso a query can check if the user's role contains a permission for that model
12:26justin_smithbut to do article by article is even a finer granularity than that
12:26grncdrrurumate: that should work in clojurescript
12:26sritchiethe site I'm working on lets users create these athletic races,
12:27sritchiejustin_smith: so what this is trying to get at is, are you the admin for this particular race that you're on
12:27justin_smithsritchie: what about a table that assigns a set of races to each user, and just check that?
12:27sritchiejustin_smith: and to find out what race the server's trying to fetch, just use a dynamic var holding the current request?
12:28rurumategrncdr: sorry, should have try it before :~)
12:28justin_smithfriend for authentication (it tells you who they are), then your own schema for authorization
12:28justin_smithsritchie: I use a controller that is a function from request to rendered template
12:29justin_smithso no need for a dynamic, it knows the info for the template it is rendering, and can do the appropriate checks based on request
12:29sritchieokay, that was the rub
12:29sritchieI want to also use friend for authorization,
12:29sritchiewhich constrains the checks I can do
12:29sritchiebut yeah, what you're saying is what I'm doing now, and it works
12:30sritchieso maybe I'll just stick with that :)
12:30justin_smithI only mention it because it is what I do
12:30justin_smiththere may be something better that leverages friend that is better for all I know
12:30justin_smithbut really using args is better than dynamic vars, in general
12:31sritchieagreed
12:32muhoosritchie: i wrote my own rbac :-/
12:32muhoothere really wasn't any other way. it's not complete, and it's specific to this app, but it kinda sucked to have to do that.
12:33sritchieI think friend would be nice if it just allowed a user's roles to be a function from request -> roles
12:34muhooi wrote some ugly crap to turn reqs into authed userids
12:34muhoobased on friend's :identity
12:35sritchiemuhoo: ah, you were using friend and still wrote your own rbac?
12:35justin_smithan advantage to resolving authorization in the controller rather than at authentication, is it fixes the problem of long sessions and changed permissions
12:35muhoofriend doesn't do rbac. it'll let you assign users roles, yeah, and it makes that a lot easier. but then to actually assign activities in the app to those roles, that i had to do myself.
12:36muhooso it's like, user->role friend will do. but role->funtionality-in-the-app i had to do, and there wasn't any ready-made framework for that
12:36justin_smitheven the user-> role thing is cleaner if resolved for each request rather than once at authorization
12:36justin_smithbecause you can change roles
12:36muhoogood point. hmm.
12:36sritchieyup
12:36justin_smithmuhoo: functionalit-in-the-app is turing complete :)
12:37justin_smithso better to let a programmer do that themselves
12:37muhoono, there are cms'es that do a lot of that for you.
12:37muhooand there are rbac systems that provide some kind of utilities to make it a bit easier.
12:37justin_smiththere are, but they are also a cms so they know you are using their model
12:37muhoojust not in clojure afaict
12:38justin_smithcaribou has a cms by default, which has roles/permissions, but some of the final steps (web UI for permissions etc.) are still in progress
12:38justin_smithalso, permissions are per-data-model, not per-instance
12:38muhooi looked at that a bit last night, didnt' see the cms stuff.
12:38muhooi should see what pedestal does
12:38justin_smithmuhoo: default page has a link to the admin
12:39justin_smithstart up the app, go to the page, click the admin link
12:39muhoois there a demo app up somewhere, like on heroku?
12:39justin_smithmuhoo: lein new caribou is the demo app
12:39muhoofor the lazy who don't want to install the thing :-)
12:39justin_smithwe aren't going to let you access the admin on our machine, sorry :)
12:40muhoonaw, i meant on heroku or something. like the friend auth demos.
12:40justin_smithputting it on something like heroku is an idea, true
12:40justin_smithwe have heroku install out of the box
12:41justin_smithbut really it isn't much of an "install" lein new caribou myapp; cd myapp; lein caribou migrate; lein ring server
12:41justin_smiththen you can rm -rf myapp if you don't want it any more
12:41swarthyjustin_smith: I think he is saying, demo app : try new project :: screenshots : try new video game
12:41swarthyI don't know if I agree or not.
12:42muhoojustin_smith: clojure.lang.ArityException: Wrong number of args (1) passed to: migrate$migrate
12:42justin_smithI am considering putting up a heroku demo
12:42justin_smithjust saying the current situation is not a super high barrier of entry
12:42muhoofollowing your instructions above
12:42justin_smithheh
12:42justin_smithoops!
12:42muhooswarthy: so, that actually is what i'm saying :-)
12:42muhoothat's 30 seconds of my life i'll never get back
12:42justin_smithlein caribou migrate resources/config/development.clj
12:42justin_smithI always forget that arg
12:42justin_smithlol
12:43swarthymuhoo: lol, yeah I see your point.
12:43muhoohttpkit, eh?
12:43muhooand leiningen-2.0.0
12:44muhooand now all of jboss is downloading, so that's really why a web demo is nice: frictionless demo
12:44justin_smithjboss?
12:44justin_smithwtf
12:44justin_smithI'll have to talk to patchwork about that
12:44muhooyep, migrations pulled in all of jboss and immutant
12:44justin_smithmust be the immutant thing;
12:44justin_smithI was just gonna say
12:44justin_smithI have been trying to ditch that dep
12:45muhooooh pretty
12:45muhoodid you do the design in-house or hire a designer?
12:45justin_smithwe are mostly a design shop
12:45justin_smithus monkeys just make the designs real :)
12:46justin_smithglad you like it
12:46muhooah, it's MVC
12:46justin_smithyeah
12:46justin_smithit's a migration of a php system that got reimplemented in ruby - but reimplemented very smartly, if I may compliment my coworkers
12:47justin_smithfrom ruby to clojure, of course
12:47rurumategrncdr: finally got round to trying it; not working
12:47rurumateUncaught TypeError: Object [object Object] has no method 'indexOf'
12:47grncdroh, that's annoying.
12:48grncdrI (wrongly) assumed that the vector implementation would have indexOf
12:48muhoojustin_smith: it's very slick. the gui for adding models feels very ruby-ish. nice.
12:48justin_smiththanks
12:48grncdrin that case, you can always do it manually
12:49rurumateyeah, I'm already digging out (loop)
12:49justin_smiththe deal is, if clojure makes us faster, they don't increase our workload, they let us put more work into improving the libs - so we have lots of incentive to make the libs work well (so dev time is shorter) and much time to make things slick
12:49grncdr,(first (filter #(= % 2) [1 2 3]))
12:49clojurebot2
12:49swarthyjustin_smith: so what is the design goal of Caribou? Is it a rails-y type thing. You guys likely do a lot of client work so Caribou tries to solve the issue of making CRUD after CRUD app for clients?
12:49grncdroh wait, that get's the value, not the index :|
12:49rurumateexactly
12:49justin_smithswarthy: yeah, client work: make a web app or web site with short turnover and a cms so producers and frontend can do as much of the work as possible
12:50grncdr,(map-indexed vector [1 2 3])
12:50clojurebot([0 1] [1 2] [2 3])
12:51swarthycool
12:51grncdr,(first (filter #(= (second %) 2) (map-indexed [1 2 3])))
12:51clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$map-indexed>
12:51grncdr,(first (filter #(= (second %) 2) (map-indexed vector [1 2 3])))
12:51clojurebot[1 2]
12:51grncdrhah, closer, but getting uglier :P
12:51swarthyjustin_smith: I think clojure as a community needs a railsy all-in-one type environment to grow with/from.
12:51grncdr,(first (first (filter #(= (second %) 2) (map-indexed vector [1 2 3]))))
12:51clojurebot1
12:52mdrogalisI kind of felt that Pedestal was supposed to be that, swarthy.
12:52grncdrrurumate: that works ^^ but is ugly
12:52mdrogalisThen again, I don't use it.
12:52rurumatestill shorter than a loop, thanks
12:53swarthymdrogalis: Doesn't pedestal aim to make single page javascript heavy apps easier. Not the standard CMS type stuff, I could be very wrong.
12:53mdrogalisswarthy: I could be very wrong too :) *Shrug*
12:54grncdr,(first (clojure.contrib.seq/positions #{2} [1 2 3]))
12:54clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.contrib.seq>
12:55grncdrpoop
12:55muhoojustin_smith: well it's very cool, will have to poke around at it some more. it looks like you put a lot of work in to it, especially making the front end very polished
12:57rurumate,(some (fn [[idx v]] (when (= 2 v) idx)) (map-indexed vector [1 2 3]))
12:57clojurebot1
12:57swarthymdrogalis: yeah if you check this out: http://pedestal.io/documentation/application-overview/ I feel like there goal is to be the rails of the future when everything goes single page.
12:57muhoojustin_smith: interesting. why is the cljs source in resources instead of src or src-cljs or similar?
12:58justin_smithmuhoo: not sure, patchwork would be able to tell you when he logs in I think
12:58mdrogalisswarthy: Understood :)
12:59swarthymdrogalis: that said pedestal looks really cool
12:59justin_smithone difference between pedastal and caribou is caribou assumes frontend isn't a clojure programmer
12:59justin_smithrealistically, that is what we have seen
12:59quilemuhoo: justin_smith: it might have to do with the browser needing to access the cljs source for debugging
13:00seangroveswarthy: pedestal is unlikely to be the framework of the masses - possible, but unlikely. It's such a different approach that there's a very large up-front investment required.
13:01grncdrrurumate: FWIW I found a nicer approach here on SO http://stackoverflow.com/a/4831170/446634
13:01swarthyseangrove: wouldn't you say that is a bit true of clojure as well though?
13:01seangroveswarthy: Yeup.
13:02muhooi'll bet the datomic console was built in pedestal
13:02muhooas an example SPA
13:05danneuanyone know of standard ways to add randomness to SecureRandom?
13:05danneueven conceptually
13:06justin_smithdanneu: you can use a adc (sound card input) as an entropy source
13:06justin_smithor even better if you have radio input
13:07justin_smithhttps://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/
13:07TimMcdanneu: On Linux, I think telling the user to use their computer normally for a few minutes is good. Timing information is juiced into the main entropy pool, and I think SecureRandom is seeded from that.
13:07justin_smithyeah, it farms out to OS entropy sources
13:07justin_smithwhich in turn can use user activity, devices with analog input, whatever
13:09muhoo/dev/urandom
13:09muhooi let the system do it.
13:10justin_smithmuhoo: yeah, it is using the same kernel functionality that generates the urandom interface
13:10danneuWhat if /dev/random is compromised?
13:10justin_smithso actually you don't need to do that, the jvm will access that in an OS appropriate way when seeding (as described in my link above)
13:11justin_smithdanneu: the jvm will not help you fix the fact your hardware or OS is compromised
13:11justin_smithtotally not in its scope of design
13:11justin_smithcompromised box is compromised box, they could compromise the jvm implementation itself at that point
13:13danneuhaha, right. so does it make sense to attempt to bolster securerandom at all?
13:13muhooby the way, peridot is awesome.
13:16justin_smiththis peridot: https://github.com/xeqi/peridot
13:16danneubasically, i have an application that derives bitcoin keypairs from a master seed. i'm not cocky enough to think anyone will ever use it - so it's merely a thought exercise
13:16justin_smith?
13:16`cbpno template by the name login.html
13:17TimMcdanneu: No, just grab (SecureRandom/getInstance "SHA1PRNG")) and call it good.
13:17mtpwhy not dual-ec!
13:17mtp/s
13:17TimMc:-P
13:18TimMcdanneu: Where are you needing to generate your own randoms?
13:18TimMcI would expect you'd be able to call into an existing crypto lib for anything at this level.
13:19danneuTimMc: the app generates the seed for the user
13:19TimMcAh, so this isn't really the crypto part, just a master secret.
13:19danneuyeah, beyond that i lean on bouncycastle
13:21danneuill see if i can find some gimmicks to add to the seeding process. like justin_smith's soundcard idea
13:21danneugive it a nice CSI gui
13:22muhooin other words, <3 : https://www.refheap.com/20814
13:23justin_smithdanneu: if you can dip into the noisy analog realm, you can get shitloads of entropy real cheap
13:24rasmustoheh, dip
13:24justin_smithhell, checkout out how many bits of resolution you have on CPU temperature readings, and if you have enough, do some munging of the least significant bits
13:25danneujustin_smith: cool, gave me some google terms to search for. would even be fun to have enduser turn on their webcam
13:25danneuand dance for their seed
13:25muhoothe idea of hand-rolling crypto seems dangerous to me. i prefer to leave it to the OS (if the OS is good) and well-tested mature open source libraries
13:25llasramContext is everything
13:26muhooi figure if the java crypto libs use system's PNRG, and system is linux, i'm fine there.
13:26justin_smithdanneu: http://hackaday.com/2010/02/06/hardware-based-randomness-for-linux/
13:27justin_smithmuhoo: not hand rolling crypto, but getting a good input to a known good off the shelf algorithm
13:27cYmenhm...just wanted to start reading noir tutorials and it tells me it is deprecated
13:27danneucYmen: check out compojure
13:27cYmenDoes it have good tutorials?
13:28cYmenI need an easy start. :)
13:28danneucompojure is easy
13:28danneulein new compojure myapp
13:28danneunoir was extracted into a library https://github.com/noir-clojure/lib-noir
13:28cYmenhmhm
13:28cYmenokay ...any particular compojure introduction or tutorial I could read?
13:29danneuwell, what do you want to do?
13:29cYmenuh.. make a website :)
13:30cYmenOr, webapp as they like to call it theses days...
13:31danneucYmen: start off with the lein template. then `lein ring server` from it to boot it and open the browser.
13:31cYmenYeah, I already played with ring but now I don't feel like just starting with my own templates and stuff.
13:32danneu?
13:32cYmenI'll just read https://github.com/weavejester/compojure/wiki
13:32danneucYmen: sure, but i meant that the lein-template sets up the barebones in a way that it's easy to figure things out from there
13:33cYmenI'll just give it a go then...
13:33justin_smithcYmen: by templates and stuff do you mean templates for rendering pages?
13:33justin_smiththere are a huge number of templating engines for clojure
13:33cYmenjustin_smith: yes
13:33rkzare clojurescript questions ok in here or should I be asking #clojurescript?
13:33danneufor html, i like https://github.com/weavejester/hiccup - Just write the html in the same file
13:33danneurkz: they here
13:34justin_smithyeah, if the person making the templates is the same one writing clojure code, something like hiccup or enlive is great
13:34augustlhow do you write a map as edn?
13:34augustlclojure.edn only has reading it seems
13:34justin_smithaugustl: pr-str
13:34justin_smithin general
13:34cYmenhiccup...will look at it soon
13:35rkzI'm trying to figure out how to do: 'webkitMatchesSelector' in Element.prototype in cljs. (contains? "webkitMatchesSelector" (.-prototype js/Element)) doesn't seem to work
13:35justin_smithfor anything to output to edn
13:35augustljustin_smith: ah, cool
13:35justin_smithor pr
13:35danneucYmen: yeah, hiccup(html) + compojure(routing) is the simplest stack of all the surrogates (sinatra, flask, express, etc)
13:36cYmenexcellent I hope it will also be easy ;)
13:36rkzI can get the function out by doing (.-webkitMatchesSelector (.-prototype js/Element)) but not sure what the cljs translation of the js 'in' operator is
13:36danneucYmen: i actually got in to clojure from the webdev angle, so lemme know if you need help
13:36seangroverkz: indexOf?
13:37cYmendanneu: thanks!
13:38TimMcrkz: Yeah, contains? checks for a key, not a value.
13:38TimMcOr wait, that's what you want, isn't it?
13:38rkzTimMc: that's what I think i'm trying to do
13:38rkzcheck if a key 'blah' is in object foo
13:38TimMcI think you have the args backwards.
13:39rkz(contains? foo 'blah') instead of the otherway... I'll try it
13:40TimMc(It's rare to see someone asking about contains? and actually needing that fn instead of a value-finder.)
13:41justin_smithyeah, lol
13:43danneucYmen: https://www.refheap.com/20817
13:43rkzTimMc: you were right, I am using it the wrong way around but it still doesnt work when I've got the args in the right order...
13:43acb_okmessage for operator
13:43acb_ok-----BEGIN PGP MESSAGE-----
13:43acb_okVersion: GnuPG v1.4.11 (GNU/Linux)
13:43acb_okhQEMA2AZRvNf4fCzAQgAhM9fhO9y1VJ4lQ75vgYklLogRubPF4EZI8owcEtgzoYF
13:43acb_okW0+hipJCBxJR7x0SXV6SpzCWqpGYibBHT/3HVwDHwxdMWBjutOtNknFRkQeT6c1F
13:43acb_okojsUPjn2+sBTrCjnUap4XmCsUe82o0bFxQ4qkhLNRVpklbgmMIKnkB9yDj1f19dQ
13:43acb_okEW+JG7boP10usXz+m3KC0fpFxIILcZEnmOSizHuijUGh5TcfUCgouI4mLYyEEol8
13:43acb_okHnEAOsP5w+4SpwJERUWXBkHdQGUNrjpnKxz5q2WbTi61jqt3I2JsY4Zbz6s4yzGR
13:43acb_okSvq38b0v1Toc/LaHZU1jQlZJC8oujEDsRUbLkUCZONLpAazkDJX/WzA355RAt8l8
13:43acb_ok7Iq76W9BfqvOabOF7rVzvxzC9TIdthjWJKoGDRdUXxIQ0goMuJYo9GbBurzePgtN
13:43acb_oksXYeeNhDapZv35+v5tU3IicjekEsF0X3iVZecgrbI94DNuOf51XqtP6YxBEmrEck
13:43acb_ok4GkQ4uJHGXRWQsqO1yMSZulFdLequ/OS0rm+EksPBsyd7OyXEy7GC67DNtr6Trz+
13:43acb_okkIr3LOeFjRb0QfyfLqXKrCmzimsBEXFmyTEhdE1EAOrsn9Z8nSFQkJ+v55hNFM+T
13:43acb_oknCJbUzv/hpFExbDAADNABkNb+SKf2CYYPS1ys4JbfEQDvTTeHM5AqTXmTe3O85oP
13:44danneu^_^
13:44llasramHuh
13:45cYmendanneu: thanks...trying to figure out routes right now, looks great, though
13:45seangroverkz: Does contains? work with native js objects?
13:47swarthyrkz: you might want to read this http://stackoverflow.com/questions/135448/how-do-i-check-to-see-if-an-object-has-a-property-in-javascript
13:47swarthythen find out if contains? does that for a javascript object
13:48swarthyto my knowledge JSON doesn't have the concept of 'index' because it is purely associative
13:48swarthyand contains? is index based isn't it?
13:48justin_smith,(contains? {:a 0 :b 1 :c 2} :b)
13:48clojurebottrue
13:48justin_smithis that index based?
13:48swarthyyes, but that isn't a json object
13:51swarthythis is why clojure + cljs is so hard to get started with. Because that hosted platform benefit means you are learn 1+N stacks at a time.
13:53rkzswarthy: thanks reading now, I made a cljsfiddle of what I'm trying to do
13:53rkzhttp://cljsfiddle.net/fiddle/r4vi.cljsfiddle
13:54swarthyrkz: I'm no expert I was just messing with Harp.js and ran into a similar issue where my lack of JavaScript knowledge about how json objects work was frustrating.
13:54seangroverkz: You can't do (keys js/window), so I don't think contains? will work
13:55justin_smithis this where you want .hasOwnProperty? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
13:57rkzjustin_smith: hasOwnProperty would work, (so would just accessing it and checking for nil) but I guess I'm trying to figure out how to do 'foo' in obj in cljs for future reference
13:57seangroverkz: We'll find you a solution, don't worry, but it's worth looking at the source here: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L1219
13:57seangroveNot that it calls (get coll ...) rather than aget
13:58seangroverkz: See http://cljsfiddle.net/fiddle/sgrove.r4vi.cljsfiddle
13:59swarthyjustin_smith and my article seems to work to: (print (.hasOwnProperty js/window "foo")) ;; should be true
13:59swarthythat prints true
13:59justin_smithcool
14:00rkzyeah hasOwnProp would work, maybe that's what the in operator calls
14:03seangroverkz: Finally, you can do (some #{"foo"} (.keys js/Object js/window))
14:03muhoois there some way in nrepl.el to copy the output of an exec to the kill ring so i can paste it?
14:04seangroverkz: Depending on what you're trying to do, I'd write a function called aget-own and use it with (if-let [foo (aget-own js/window "foo")] ...)
14:13rkzseangrove: yep that's what I'll do thanks! but this is an interesting problem I'm going to update the fiddle with a few edge cases
14:14bitemyappswarthy: at least as far as CLJS goes, you were never going to avoid having to learn the DOM
14:15bitemyappyou are *kidding* yourself if you think you can get away with that in a client-side context.
14:15swarthyi never said I was
14:15bitemyappswarthy: server-side has a higher likelihood of having a "common core" interface to the host.
14:15swarthyyeah
14:15muhoocljs means learning dom. clojure means learning java and jvm. these are hosted languages.
14:15seangroverkz: With some more understanding of what's happening here, it's useful to see how lynaghk extends ILookup to js objects: http://keminglabs.com/blog/angular-cljs-weather-app/
14:16seangroveThen you can use destructuring and whatnot like they're native objects - you just have to decide how to handle inherited properties, etc.
14:16bitemyappmuhoo: it's easier to avoid the Java bits than it is the DOM bits though.
14:17justin_smithmuhoo: I am playing around in the ielm repl with nrepl-send-string - it takes a string and a callback but I am clearly doing something wrong
14:17justin_smiththeoretically 'kill-new as the callback would put the output in the yank ring
14:18swarthybitemyapp: muhoo: are there any good resources that explain the JVM/Java as a platform that you would recommend. What I really want is 'The JVM for People Who Get Unix'
14:19bitemyappswarthy: I came to it from the same background, I don't think there's much to learn if you're a Clojurian.
14:19muhooswarthy: not that i know of. i'm a unix guy too.
14:19muhoooh there is a lot to learn. know what -Xmx means? what about permgenspace? what's in your ~./m2 ? etc etc
14:20bitemyappswarthy: maven is hiding underneath Leiningen, the classpath is where the JVM finds...classes (-cp) and you want to pay attention to how much heap you're providing for your JVM (-Xms -Xmx)
14:20justin_smithmuhoo: (kill-new (second (nrepl-send-string-sync ":hello")))
14:20bitemyappswarthy: there's honestly not that much to it unless you get specific.
14:20swarthyyeah
14:21muhoothe problem is when things break or act unexpectedly, then you are looking at something and goign WTF
14:21muhoosome exposed underlying java or js thing in the host language. it's inevitable, eventually.
14:21swarthybitemyapp: for me it is mostly about structuring work and building web applications with Clojure \ JVM as the platform where it used to be unix.
14:21mercwithamouth=P
14:21swarthybitemyapp: muhoo: like, how do I replace crontab with a cljoure app? message-queue? there is a lot of ambiguity for me now.
14:22seangrovebitemyapp: Missed a good talk last night, was pretty interesting the hear some of the insights from StaplesLab
14:23muhooswarthy: wow. well raynes wrote a library to do cron pretty well. i'm about to start using it. there's core.async for messsaging inside the app, and libraris for using AQMP and such.
14:23seangroveI personally appreciated the differences between code and data
14:23swarthythat is mostly what I'm speaking about, but I realize that I didn't know anything about Unix either until I did.
14:23swarthymuhoo: yeah, cool.
14:25justin_smithmuhoo: better example (kill-new (second (nrepl-send-string-sync "(zipmap (map (comp keyword str char) (range 97 256)) (range 26))")))
14:25swarthymuhoo: I'll have to look into that crontab thing. I guess if I use ruby or python even if I don't understand what is happening I understand unix below it. Now I am just terrified because I learning clojure and learning the JVM is like learning to drive: only the car is a flying car.
14:25swarthybut its fun though
14:27ToxicFrogswarthy: wait, are you writing a cron replacement in clojure?
14:27swarthyToxicFrog: no
14:27justin_smithToxicFrog: I think he means more that he once relied on being able to use cron, but that is not part of the jvm, and he is trying to do everything within the jvm as an ecosystem
14:28justin_smiththough yeah, you can still use cron
14:28swarthyjustin_smith: yeah that is mostly it. Not so much that I don't want to use it. But that the tools I once had don't make sense in this strange new land.
14:28swarthySo its a fun thing learning the new ways.
14:28bitemyappseangrove: there was a talk last night?
14:29bitemyappseangrove: dammit, meetup.com has failed me.
14:29justin_smithyou could totally make cron send a request to your webapp
14:29justin_smithfor example
14:29eggheadgosh core.async is just so cool
14:29swarthyjustin_smith: yeah like hit an api endpoint with curl?
14:29justin_smithright
14:29patchworkegghead: Agreed. It is so natural I don't know how I lived without it
14:29clojurebotYou don't have to tell me twice.
14:29bitemyappseangrove: yeah the SM meetup is on the 21st...what are you talking about?
14:30ToxicFrogI am now completely lost~
14:30bitemyappseangrove: or are you at the conj?
14:30swarthyjustin_smith: Yeah its just a very different platform and I'll have to learn to use it instead of the machine it's running on, and whatever patterns that brings about.
14:31seangrovebitemyapp: Nah, the QCon clojure talk
14:31seangrovehttp://www.meetup.com/The-Bay-Area-Clojure-User-Group/events/146268902
14:32muhooswarthy: take your time and read things first: code, books, etc. jumping in to a project under pressure with a new language on a new-to-you vm might not be the easiest way.
14:32bitemyappswarthy: if thousands of people have done something, you can probably do it too.
14:32swarthybitemyapp: ahaha. thanks.
14:32bitemyappmight take you a little more time or a little less time, but everything is doable.
14:32bitemyappexcept for proving P==NP
14:33bitemyappthat's not really doable for most people.
14:33swarthyheisenberg uncertainty?
14:33swarthyisn't that what that is? Or am I off?
14:33bitemyappswarthy: I'm serious though, people put their goals/desires on a pedestal when most of what they want for themselves has been done many times before. World is your oyster yo.
14:33bitemyappno, but it's not the point
14:33swarthybitemyapp: yeah I got you. I'm not saying I can't do it and I appreciate the pep talk.
14:34swarthymuhoo: I have been going slow. I wanted to learn clojure but needed to learn Lisp first. So I started with SICP a few months ago.
14:34swarthytrying to learn the platform itself now
14:34bitemyappswarthy: don't worry, there's a bamboo cane to go with the pep talk if you slack off.
14:34swarthybitemyapp: ahahah
14:34bitemyapp^^ he thinks I'm kidding.
14:35swarthybitemyapp: You were talking about seriously functional stuff the other day and possibly haskell if I remember correctly?
14:35bitemyappswarthy: da
14:35bitemyappkinda, anyway.
14:36swarthybitemyapp: how do you view haskell as a clojurist as well?
14:36bitemyappI was talking about applicative functors as a more general alternative to ML-style modules.
14:36swarthyi've played with it a little.
14:36swarthybitemyapp: I'm not familiar with ML.
14:36bitemyappswarthy: Haskell-esque type systems and languages are the future even if Haskell itself isn't.
14:36bitemyappcore.typed is interesting.
14:37swarthybitemyapp: In what way?
14:37bitemyappwe can't really "build upwards" unless we can trust the code underneath us to "just work"
14:37bitemyappthat can't really happen with pure code, equational reasoning, and a useful type system.
14:37bitemyappwithout*
14:38swarthyhave you every see gary bernhardt talk about functional core imperative shell?
14:38bitemyappswarthy: I really enjoy Clojure, it's very practical.
14:38swarthyseen*
14:38bitemyappswarthy: gary bernhardt is a self-important prick.
14:38swarthybitemyapp: ahahah
14:39swarthyI'll take that as a yes then.
14:40swarthyYou don't think that purely functional systems run into the same issues as purely object oriented. Ie: monads could be seen as a pattern in the way java design patterns are, trying to resolve a conflict brought about by extreme-ness.
14:40bitemyappno, for several reasons
14:40bitemyappalthough it's a good question
14:40swarthylove the hear the counter argument
14:40swarthylove to*
14:40bitemyappfor one thing, OOP design patterns are verbose and not composable. They're also typically not type system enforceable.
14:40bitemyappMonads are concise, mathematically clear, composable, and can be enforced by the type system.
14:41bitemyappI wouldn't say the two are comparable at all even if they solve *vaguely* similar problems
14:41bitemyappbut they're vaguely similar problems arising from very different approaches.
14:41bitemyappOOP is DOA.
14:41bitemyappthere's no hope without purity, OOP is too stateful. You just can't get very far with that.
14:41bitemyappsome components of OOP are useful and Clojure intelligently ripped those parts off.
14:41mdrogalisstrangemonad disagrees. He's out.
14:41swarthymdrogalis: lol
14:42mdrogalisLeon Repl should make an appearance soon.
14:42mdrogalisIf I ever get in trouble with the authorities, I'm going with that as my name.
14:43swarthybitemyapp: so if haskell is the start of the future, how does that reconcile with clojure's take on the future? or are they compatible in some ways?
14:43muhooTHE FUTURE
14:43swarthymuhoo: indeed
14:43bitemyappswarthy: there are differences. Clojure is making the bare bare basics of FP more accessible to current programmers. That's extremely useful.
14:44mdrogalis~future
14:44clojurebotmdrogalis: the fn created by future (like all fns) doesn't close over dynamicly scoped stuff
14:44swarthybitemyapp: do you think that a person would benefit from learning in a more strict environment though? where purity is enforced like clojure and you can't rely on old ways as in clojure?
14:44bitemyappOn the negative side, Clojure seems to be optimized for people with perfect knowledge of their system, design, and dependencies.
14:44bitemyappswarthy: don't use the word strict, it's not descriptive here.
14:45swarthysure, pure then
14:45bitemyappswarthy: Haskell will teach you "more FP" than Clojure, but Clojure is a real pleasure to hack in. porque no los dos?
14:45swarthyyou have to be functionall all the time
14:45bitemyappHaskell has a lot of escape hatches, don't kid yourself.
14:45bitemyappyou just shouldn't use them while learning.
14:45swarthysure, and you can have both. I'm just quizzing you because you know more and are quickly filling gaps in my understanding.
14:45justin_smithswarthy: haskell has peek and poke
14:45gf3technomancy: I just wanted to say that leiningen is a pleasure to use
14:45bitemyappswarthy: the rabbit hole goes deeper than Haskell too, if desired.
14:45bitemyappTT languages exist
14:46swarthyTT <- don't know that one
14:46bitemyapptype theoretic
14:46bitemyappCoq, Agda, Idris are good examples.
14:46swarthyIdris, love the name.
14:47bitemyappswarthy: one of the key lessons of Haskell, Coq, Agda, and Idris is that the more power you give up, and the more declarative you are when you describe your needs to the computer, the more help you get from the computer.
14:47swarthyYeah this is all cool stuff. After learning Lisp it lead to this FP revolution, and I find it all far more exciting than anything from python, or other OOP stuff.
14:47bitemyappswarthy: eschewing turing completeness when it's unnecessary, for example.
14:47bitemyappor in a parsing context, shifting from a context sensitive to a context free grammar, or from a CFG to a regular grammar.
14:47swarthybitemyapp: interesting on the power == reduction. did you see uncle bob's talk on Clojure as the last programming language?
14:48bitemyappswarthy: I did. I disagree but it was flattering to Clojure anyway.
14:48bitemyappthere will not be a "last" programming language
14:48swarthybitemyapp: yeah, he conveys the: things get better the more we restrict ourselves which I find in line with a lot of what Hickey says as well.
14:49AimHereThere will be. It's called 'Javascript'
14:49TimMcbitemyapp: There will, but not soon.
14:49bitemyappAimHere: go to hell and die.
14:49swarthybitemyapp: ahahha
14:49TimMchahaha
14:49swarthyahahha
14:49swarthywow I am truly LoLing.
14:49swarthythat hurt
14:49TimMcbitemyapp: "How may entropy be reversed?"
14:49danneui dont think it's easy to rely on old ways in clojure. now scala though, you can write it just like you'd write java
14:50bitemyappwhich is one of the things I don't like about Java
14:50bitemyapper, Scala.
14:50danneuyeah, same
14:50bitemyappFreudian slip, ended up coming out right anyway.
14:50bitemyappI would only agree to Scala if I could attach a taser equipped to fire upon typing "var" to my coworkers.
14:50bitemyappflatMap or fuck off.
14:51rasmustobitemyapp: val ok w/ you?
14:51danneuhoping that coworkers opt in to FP in scala is like hoping they opt in to documentation
14:51danneui dont like being hopeful
14:52bitemyapprasmusto: not like point-free is nice in Scala.
14:54OlegYch4danneu: https://github.com/puffnfresh/wartremover
14:55danneuoh cute
14:55cYmendanneu: You get to do Scala at work? I envy you.
14:55danneui dont
14:56danneui dont work with scala*
14:56swarthybitemyapp: so one last question, why is haskell the template for the last programming language but not the last language itself?
14:56muhoobitemyapp will write a book one day. it'll be called "coding with ATTITUDE" and a taser will be included in the hardcopy book.
14:57lumaficYmen, at my current company, i've only worked with scala and clojure 8)
14:57cYmenmuhoo: or maybe the cover will have really pointy edges
14:57muhoochapter 3 will be called "flatMap or fuck off"
14:57cYmenlumafi: Is that a one man company?
14:57muhoochaper 4 will be "javascript go to hell and die"
14:57lumafinot even
14:57cYmenDo you hire? :p
14:57muhoothe cd companion will include death metal bands
14:57lumafisure, you willing to relocate?
14:57bitemyappswarthy: People have needs that vary too much for a single implementation to be the answer.
14:57cYmenlumafi: Where?
14:58lumafifinland ;)
14:58bitemyappswarthy: and again, I think Haskell is *headed* in the right direction, it's not the final state at all.
14:58bitemyappswarthy: I would reiterate that things like Idris and Agda exist...
14:58swarthybitemyapp: i see, and what idris and agda provide haskell is missing?
14:58cYmenlumafi: Have considered it but my gf is afraid the winter will make her too depressed.
14:58bitemyappswarthy: dependent typing, for one.
14:58danneuIs there a way to sponge up all the non-nil-return calls in typed-clojure?
14:59danneuthat's really been my only pain point so far
14:59muhoocYmen: they get like 6 weeks paid vacation in europe, don't they? summers in sicily, south of france, ibizia, etc, must be nice
14:59lumafimuhoo, yep
14:59lumafi4-6 weeks depending of the country
14:59cYmenmuhoo: I'm in Germany and get 6 weeks of vacation and a mild, bright winter compared to Finland.
15:00cYmenI once thought about going home from a bar in Helsinki because it was so late. It turned out to be about 8 PM.
15:01isaacsandershell
15:01isaacsandershello
15:01muhoohuh, it was pitch dark out at 6pm here, in san francisco last night IIRC
15:01muhoodamn PST8PDT
15:02isaacsandersDoes anyone know how to access a logarithm function in clojure?
15:02`cbpMath/log
15:02isaacsandersI am fairly new, and I have not been able to use Math/log
15:02danneuwhen in doubt just google for the java answer
15:03isaacsandersI get "CompilerException java.lang.RuntimeException: Unable to find static field: log in class java.lang.Math"
15:03`cbp,(Math/log 2.7)
15:03clojurebot0.9932517730102834
15:03swarthybitemyapp: cool. googled dependent types. Thanks for the FP brain dump! Learned a lot.
15:03swarthy,(Math/log10 1000)
15:03clojurebot3.0
15:03TimMcbitemyapp: Misread that as "despondent typing". I guess that goes with Abject-Oriented Programming?
15:04bitemyappswarthy: np
15:04bitemyappTimMc: totes. Match made in Hell.
15:04isaacsanders,(print "my clojure doesn't work with it, does anyone have any ideas as to why?")
15:04clojurebotmy clojure doesn't work with it, does anyone have any ideas as to why?
15:04TimMchttp://typicalprogrammer.com/abject-oriented/
15:04swarthyisaacsanders: What do you mean by doesn't work? What is the error?
15:05`cbpisaacsanders: maybe you're forgetting the parenthesis?
15:05isaacsanders:P
15:05isaacsandersit doesn't appear to exist as a value...
15:05isaacsandersI feel dumb.
15:05TimMcisaacsanders: Math/log is a method, you can't pass it around like a function.
15:05isaacsandersok
15:05isaacsandersback to the code.
15:05isaacsandersthanks
15:06TimMcIf you want to map it across a collection, use #(Math/log %) or soemthing.
15:06swarthyTimMc: he left
15:06TimMc:-(
15:06swarthyvery wham bam thank you mam of him
15:06swarthyHe should have at least stayed for a cuddle.
15:07TimMcYeah, what kind of IRC user does e take me for?
15:07swarthylol
15:16mdrogalislol TimMc
15:21pbostromdoes 'lein trampoline repl' not start an nREPL server?
15:27clintnewsomphostram: can't you just do lein repl :headless
15:27clintnewsomthen connect to that repl>
15:28pbostromclintnewsom: I'll look into that; lein trampoline does some trickery so that only one JVM instance gets started, not sure if :headless does the same thing
15:30TimMcpbostrom: There are still 2 JVM invocations. trampoline writes out the invocation to a shell script, then launches it and dies.
15:31TimMcIIRC there's a LEIN_FAST_TRAMPOLINE env var that caches those invocations so the first JVM launch can be skipped the next time around.
15:32cYmenIs there a way to write dependency entries like [ring/ring-jetty-adapter "1.2.0"] without the explicit version number? I am usually fine with the newest version...
15:32gunsLEIN_FAST_TRAMPOLINE is great; just have to remember to bust the cache after restarts
15:34pbostromTimMc: ah, right; in any case, I can't tell if lein trampoline repl starts the nREPL server, and if so, what port
15:35edbondcYmen, afaik version is required. Take a look a lein ancient plugin
15:36TimMcguns: Restarts?
15:36gunscYmen: I use "LATEST" for plugins in my profiles.clj; I wouldn't recommend for an actual project however
15:37gunsTimMc: /tmp/ is typically wiped on restarts
15:37cYmenguns: Yeah, I'm not doing anything productiony so far.
15:37gunsmachine reboot I mean
15:37cYmenguns: Thanks!
15:43TimMcguns: It doesn't handle that gracefully? Sounds like a bug.
15:43gunsTimMc: I believe it's mentioned in the docs
15:45cYmenIf I want to check for the presence of a session variable, can I use compojure routes for that?
15:50swarthycYmen: you may want to look into lib-noir. I'm not very experienced with it myself but it wraps your route handles and provides session management.
15:50cYmennoooo
15:51cYmenswarthy: sorry, just ...so many libs to learn
15:51swarthyits not really more than say rails. Its just they aren't all in one 'thing'.
15:52swarthycYmen: this book is worth it http://pragprog.com/book/dswdcloj/web-development-with-clojure
15:53cYmenhm...not sure if I should read that now, just after chapter 1 of "joy of clojure" :)
15:53swarthywell... if you are trying to make web apps in clojure that is the way to learn about it.
15:53swarthykeep it in mind
15:54cYmenSo it is actually a good book?
15:54swarthyi have joy of clojure as well and like that book
15:54swarthyi think so, the guy who wrote it goes by yogthos, he is usually in this channel
15:55swarthyyou could ping him and ask questions if you need to.
15:55cYmenyogthos: Should I buy your book? O_o
15:55bitemyappswarthy: joy of clojure wasn't written by yogthos.
15:55bitemyappswarthy: yogthos wrote Clojure Web Development.
15:55swarthythat is what I meant
15:55swarthywe are talking about both
15:55bitemyappJoy of Clojure is good, but it's not an intro book.
15:55cYmenYeah, I got that.
15:55yogthoscYmen: yes? :)
15:55swarthylol
15:55bitemyappClojure Web Development is a good way to learn idiomatic Clojure web dev with Ring.
15:56bitemyappit will not teach you alternative and less common stacks like Pedestal though.
15:56yogthosalso it's a general intro to the language in the context of making web apps
15:56bitemyapparohner: I'm allocating time at work to improve brambling.
15:56arohnercool!
15:56bitemyapparohner: if you have requests other than the obvious need for incremental migrations, speak up!
15:56cYmenThe Brambling (Fringilla montifringilla) is a small passerine bird in the finch family Fringillidae.
15:56arohnerI haven't used datomic in anger yet
15:56bitemyappcYmen: ding ding ding. that's it.
15:57bitemyapparohner: damn, well I'd better say something in #datomic then.
15:57`cbpanyone need some help with their open source
15:57cYmenyogthos: Thanks!
15:57arohnerjust a few demo projects, but I'm planning on using it in prod soon
15:57yogthoscYmen: np :)
15:57bitemyapp`cbp: you need another project? lol.
15:57bitemyapp`cbp: want one off my list?
15:58`cbpbitemyapp: always moving on
15:58bitemyapp`cbp: https://dataset.readthedocs.org/en/latest/ for Clojure (or a stripped down Korma).
15:58bitemyapphelp me improve https://github.com/bitemyapp/brambling (if you care about Datomic)
15:58`cbpnever used datomic
15:58`cbpon the list of clojure things i need to try out :(
16:00`cbpa korma with less macros? :-D
16:00bitemyapp`cbp: well either of those projects are options, the first one plays into your strengths nicely since you did a really good job on Revise.
16:00`cbpthanks
16:00bitemyapp`cbp: yeah a stripped down Korma with less macros, no complection with connection pooling.
16:01bitemyapp`cbp: the python project I showed you is slightly different, I can explain it on Skype/voice if you want.
16:01yogthosspeaking of korma, any plans on adding a way to initialize it with a given connection? :)
16:02`cbpbitemyapp: alright sure itll have to be at night though
16:02bitemyappyogthos: sigh, that's kinda the micro-Korma I'm talking about.
16:02bitemyappyogthos: it's going to be simpler to just have a clean break, refactor the API, and remove the direct dependency on things like c3p0
16:02bitemyapp`cbp: catch me anytime that works for you.
16:03indigoOoh, micro-Korma
16:03lumafithat reminds me, i need to file a bug report for korma when i get back to work
16:03yogthosit would be nice to modularize it a bit :)
16:04bitemyapplumafi: please do :)
16:04bitemyappyogthos: you're telling me... *grumble grumble*
16:04indigobitemyapp: You should call it Couscous, since it's tiny :P
16:04yogthos:)
16:04yogthoslol
16:05bitemyappindigo: not bad, but if it's `cbp's project on which I merely consult or assist, it's his to name.
16:05bitemyappindigo: he was asking me for ideas. I'll be working on Brambling at work and I really...REALLY need to work on Simonides.
16:05pbostromif anyone here has a Twitter account and wants to try something fun, I wrote a Twitter REPL, just tweet some Clojure to @cwoio, the return value will show up as an @mention reply
16:05bitemyappI'll help on something he does if it's interesting, but I *NEEEEEED* to launch Simonides.
16:05indigobitemyapp: Good luck
16:06mattmossIf I have (filter pred2 (filter pred1 coll)), I can rewrite as (filter #(and (pred1 %) (pred2 %)) coll)... but wondering if there is a point-free way to combine pred1, pred2 and 'and' to make that new predicate.
16:06bitemyappmattmoss: that's a Monoid!
16:07bitemyappmattmoss: and the way to do that is partial.
16:07S11001001bitemyapp: what does that look like?
16:07bitemyapppoint-free isn't...great in Clojure.
16:07S11001001mattmoss: there's a variant of all in clojure.core that takes a list of predicates
16:08mattmossWell, I realize that the point-free version might be more complicated than the #(...) version. Was wondering what it would look like tho.
16:08S11001001mattmoss: I forget what it's called, every-pred maybe? anyway that should do it
16:08amalloyevery-pred, in fact
16:08indigoBleh, libusb has no Clojure bindings
16:08S11001001,(doc every-pred)
16:08clojurebot"([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns true if all of its composing predicates return a logical true value against all of its arguments, else it returns false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical false result against the original predicates."
16:08bitemyappmattmoss: you'd have to go to some trouble to make it work, clojure functions aren't written with currying in mind, let alone point-free.
16:09S11001001^^ mattmoss
16:10S11001001bitemyapp: and a pain without types anyway, if you aren't using core.typed
16:10mattmossSure, understand that.
16:10bitemyappS11001001: right.
16:10cYmenWhat does point-free mean in this context? Where is the point in #(and (pred1 %) (pred2 %)) and why does it matter?
16:11S11001001the %
16:11bitemyapptoo bad 'and is a macro.
16:11S11001001no matter, every-pred is there
16:11mattmossIt's times when I see things like (filter... (filter... )) etc that I think there needs to be a nice way to compose those without getting all weird, and every-pred seems to be that,
16:12bitemyappmattmoss: that's the idiomatic way, yes.
16:12S11001001conversely some-fn plays the same role for `or', mattmoss
16:12mgaare_every-pred has written the unattractive code, so you don't have to
16:12TimMcmattmoss: Put it all in a clojure.core/for :-D
16:12S11001001TimMc: ii eee
16:12mattmossTimMc: Hmmmm.
16:13bitemyappTimMc: that's like those python programmers that do everything in a list comprehension, ugh.
16:13TimMcIt's not a *real* program unless you've got at least 3 :where and 2 :while clauses in a for.
16:13Foxboronbitemyapp: butbutbutbut...they are so cleane and easy to read
16:13mattmosslol
16:14S11001001heh
16:14bitemyappFoxboron: this is the same BDFL that killed off reduce.
16:14Foxboronbitemyapp: butbutbutbut, we got list comps!
16:14Foxboronwe dont need map, nor filter, nor reduce!
16:15S11001001Foxboron: also have loops, no need for tail recursion
16:15bitemyapphave you ever tried to do a non-trivial fold in a list comp?
16:15bitemyappshit's insane.
16:15FoxboronS11001001: hahaha
16:15Foxboronbitemyapp: no i havent
16:15bitemyappFoxboron: it's annoying.
16:15mattmossJust someone explain to me how to break out of an outer loop from within an inner loop and there'll be no violence. KTHXBYE
16:16S11001001mattmoss: anyway, because every-pred and some-fn in a sense are mconcat for different monoids over the same type, it's easy to nest them arbitrarily
16:16bitemyapplike I said, 'tis a Monoid. :D
16:17mattmossIs a monoid a cool monad?
16:17mattmoss(inc bitemyapp)
16:17lazybot⇒ 11
16:17mattmoss(inc S11001001)
16:17lazybot⇒ 5
16:33mikerod,(true? (Boolean. "true"))
16:33clojurebotfalse
16:33mikerodbut why :(
16:34opqdonutbecause that's java for you
16:34S11001001,(if (Boolean. false) 'yes 'no)
16:34clojurebotyes
16:34mikerodI know it is *bad*
16:34S11001001whatcha want
16:34opqdonutjust don't use the Boolean constructor
16:34mikerodwell yes
16:34opqdonutthere was a Boolean/valueOf or something
16:35mikerodI think I am having an issue related to this, when doing java interop
16:35mikerodWhat is the *reason* (true? (Boolean. "true")) is false ?
16:35opqdonut,(if (Boolean/getBoolean "false") :true :false)
16:35clojurebot#<SecurityException java.lang.SecurityException: denied>
16:35opqdonutwow
16:35mikerodnot sure I have figured that out yet
16:35mikerodhah hmm
16:36opqdonuttrue? is defined as (clojure.lang.Util/identical x true)
16:36nDuffmikerod: Boolean/TRUE is a singleton. If someone follows the rules, checking for truthiness is an identity check.
16:36nDuffmikerod: whereas a value check is slower / more expensive.
16:36mikerodoh
16:36mikerodduh, it uses `identical`
16:36mikerodI didn't notice that before
16:37opqdonutand what nDuff said
16:37opqdonut,(true? (.booleanValue (Boolean. "true")))
16:37clojurebottrue
16:37opqdonutif somebody is passing you weird Booleans, just sprinkle .booleanValue everywhere :)
16:38nDuff...or go find them with a clue-by-four. :P
16:38mikerodso if I'm handed some java object, that doesn't use the Boolean/TRUE singleton and I call true? on it; I'm out of luck right?
16:38mikerodwell, .booleanValue
16:38nDuffmikerod: meaning you need to either fix their code or use .booleanValue.
16:39mikerodsounds good! :)
16:39nDuffmikerod: I'd call "fix their code" to be by far the preferable approach. Constructing new booleans is considered an antipattern in the Java world -- it's not just a pitfall when interacting with Clojure.
16:39mikerodnDuff: oh, I know. I think it is very stupid to have multiple instances of a boolean value.
16:41indigoAntipatterns, eh
16:42indigo,@@@(atom (atom (atom "antipatterns, eh")))
16:42clojurebot"antipatterns, eh"
16:42amalloyTimMc: i went looking for the crazy pit of :when/:while/:let that i wrote a while ago, only to discover that ninjudd removed it
16:43amalloynDuff: don't forget java.io.ObjectInputStream, which deserializes to (Boolean. "true") and (Boolean. "false")
16:44amalloyyou can't really fix that one, sadly
16:44nDuffamalloy: thank you kindly -- I didn't need that faith in humanity, really.
16:44danneuI have a macro that almost works, but I can't figure out how to unroll it: https://www.refheap.com/20825
16:44TimMcamalloy: D-:
16:45amalloydanneu: there is simply no way to make one form expand to multiple forms
16:46amalloyyou could expand to (do (non-nil-return ...) ...), if that's sufficient
16:46danneuoh yeah, that's it
16:46amalloyalso: klass is just gross. clojure doesn't have reserved words; you can name your classes class
16:47danneuhabit -_-
16:47amalloyanyway, you want something like `(do ~@(for [[k & m] things :let [f whatever] method methods] (let ...)))
16:48mikerodSo when you have a primitive boolean and you pass it to a method taking an Object, it is auto-boxed to one of the boolean singleton TRUE/FALSE?
16:48amalloyyes
16:48mikerodthat is good
16:50mikerodbut ObjectInputStream sounds like a fail
16:50danneuamalloy: how could i unnest them once more? https://www.refheap.com/20825
16:50amalloyyou could do literally what i just pasted
16:51amalloywell, not pasted. typed
16:51danneuoh, i see
16:51danneuroll it into one for
16:51danneuthanks
16:51amalloydanneu: alternatively, if a complicated for is not to your taste, you can always flatten a list by one level with using (apply concat nested-lists)
16:52TimMc&(let [baos (java.io.ByteArrayOutputStream.) _ (doto (java.io.ObjectOutputStream. baos) (.writeBoolean false)) o (doto (java.io.ObjectInputStream. (java.io.ByteArrayInputStream. (.toByteArray baos))) (.readObject))] o)
16:52lazybotjava.lang.SecurityException: You tripped the alarm! class java.io.ObjectInputStream is bad!
16:52amalloyTimMc: clojurebot will let you get away with it, i think
16:53TimMcI messed it up anyhow.
16:53amalloyyeah, it looks a bit confused
16:54TimMcI wrote a prim bool and read an object...
16:56TimMc,(let [baos (java.io.ByteArrayOutputStream.) _ (doto (java.io.ObjectOutputStream. baos) (.writeObject Boolean/FALSE)) ois (java.io.ObjectInputStream. (java.io.ByteArrayInputStream. (.toByteArray baos))) o (.readObject ois)] [o (if o "yes" "no")])
16:56clojurebot#<CompilerException java.lang.ExceptionInInitializerError, compiling:(NO_SOURCE_PATH:0:0)>
16:56TimMc;;= [false "yes"]
16:56TimMcYeah, that's good times right there.
16:59mikerodgood to know
17:00mikerodwonder where the decision to allow booleans to be constructed as separate instances came from
17:00mikerodI mean Booleans
17:02mercwithamouthis the oreilly clojurescript book worth purchasing?
17:03mercwithamouthi'm playing with enlive at the moment...which is 'cool' so far...but it seems if i want to do any client side work with clojurescript then enfocus is what I should take a look at?
17:07seangrovemercwithamouth: Well, one of them runs server-side, the other client-side, so presumably you'll have to pick the appropriate one
17:07seangroveIs there a way to bulk-insert rows in postgres/sql/korma/jdbc?
17:08mercwithamouthseangrove: yeah i suppose anything else would be 'messy'. at first i thought the basics I would push some html from server side but to be realistic that's just a nasty mess waiting to be made.
17:08nDuffseangrove: yes, JDBC supports that.
17:09mercwithamouthat first i was sort of happy because it reminded me of what I saw when I played with liftweb for a few months...
17:10nDuffseangrove: ...though the JDBC method (which basically builds a prepared statement and executes it a lot) is going to be slower than whatever native bulk loader your database provides.
17:10nDuffseangrove: That's something of a universal constant -- everyone all the way up to Oracle has a bulk loader that plays fast and loose on consistency checking, defers indexes, etc.
17:11nDuffseangrove: ...but anyhow, the JDBC approach will be faster (by a lot) than inserting one statement at a time.
17:11swarthyseangrove: I was curious and google gave me this: http://viralpatel.net/blogs/batch-insert-in-java-jdbc/
17:12seangrovenDuff: Interesting, checking it out now. Wonder if it's smarter to just serially insert a few thousand rows
17:12hadronzooIs there a standard way to find common default paths for different OSes (for example, ~/Documents for the documents directory on OS X, \User\My Documents on Windows)?
17:12nDuffseangrove: for just a few thousand, the JDBC interface for passing in a vector of argument lists with your query will be fine.
17:13nDuffseangrove: it's when you're in the millions where you want to use the native bulk loader.
17:13hadronzooIn other words, is there a path abstraction library?
17:13seangrovenDuff: So you mean using the JDBC batch/prepared-statement interface is the way to go for ~10-100k rows at a time?
17:14nDuffseangrove: yup.
17:14nDuff...well, maybe not when you're closer to 100k.
17:14seangrovenDuff: Great, thank you.
17:14nDuff*shrug*. Would have to test at that phase.
17:15seangroveYeah, that's completely fair, happy to run with it
17:15nDuffseangrove: anyhow, if you're using clojure.java.jdbc, see insert!
17:18brehautnDuff: evil is pretty strong; i prefer half-baked
17:18seangrovenDuff: I prefer to avoid such hyperbolic statements at all costs; they're one of the worst things in the world.
17:18swarthyhadronzoo: http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#getProperties()
17:18mattmossI just wrong #(% %2) in some code and feel weird.
17:18mattmoss*wrote
17:19nDuffs/evil/harmful/
17:19bitemyappmattmoss: that's a little odd.
17:19nDuffseangrove: *grin*.
17:20mattmoss(condp #(% %2) expr pred1? (foo ...) pred2? (bar ...) :default)
17:20swarthyhadronzoo: so you could do (let [props (System/getProperties)] ...)
17:20swarthyhadronzoo: if you wanted them all
17:20swarthyhadronzoo: typically if you can't find something search for how to do that thing in java, then see if that answer has a lib\wrapper. If not then use the java interop.
17:21hadronzooswarthy: Thanks you--very helpful. I have a database that I would normally place in /var/db or /usr/local/var/db on a *nix system. Do you know where would it normally be placed on a Windows system?
17:22justin_smith,(System/getenv "HOME") ; a useful one hadronzoo
17:22clojurebot#<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.HOME)>
17:22swarthySorry I don't know windows very well at all.
17:22justin_smithgeneralizing anything to windows is a pain
17:22justin_smithit wants to be "special"
17:23hadronzoojustin_smith: yes, that seems to be the way to go. Thanks.
17:23justin_smithalso, (System/getenv) may give you other useful stuff if you run it on a Windows box to see what they set for you
17:25hadronzoojustin_smith: Yeah, I'll try that
17:25justin_smith,(clojure.pprint/pprint (into {} (System/getenv))) ; more readable
17:25clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint>
17:26mercwithamouthhelp?? i tried starting a clojurescript project with the 'mies' template but it fails https://www.refheap.com/20827
17:28justin_smithtechnomancy: does grenchman not have a windows binary because nobody built one yet, or because it just isn't windows compatible? I don't run windows myself but someone was looking for such a tool on stackoverflow (and I assume others are too)
17:28hadronzoomercwithamouth: Try including [org.clojure/tools.reader "0.7.10"] in your project
17:28mercwithamouthhadronzoo: gotcha
17:29mercwithamouthhadronzoo: hrmm still no go
17:31cYmenHow do I output stuff to the shell (probably stdout) from my compojure route function?
17:31hadronzoomercwithamouth: I remember having that same problem and I thought that fixed it. What does your cljs file look like?
17:32mercwithamouthhadronzoo: core.cljs?
17:33mercwithamouthhadronzoo: https://www.refheap.com/20829
17:35hadronzoomercwithamouth: try (.log js/console "Hello world!")
17:36hadronzoomercwithamouth: not sure why it's crashing, though
17:37justin_smithyeah, because of the way the . macro works (log "hi") does not get expanded into a macro invocation, log needs to be moved up a level (I think (. js/console log "hi") would work too)
17:37mercwithamouthharpreet_: still a no go
17:38swarthyjustin_smith: yep that one worked in a fiddle as well
17:38harpreet_mercwithamouth: you surely didn't mean me. I am a lurker here with not enough chops to be a regular :-/
17:39hadronzoomercwithamouth: try "lein cljsbuild clean && lein cljsbuild once"?
17:39mercwithamouthharpreet_: oops, sorry =P
17:39hadronzoomercwithamouth: can you post you project.clj, too?
17:39mercwithamouthhadronzoo: ok
17:40mercwithamouth=( nope same error
17:43swarthycYmen: you could do this https://www.refheap.com/20831
17:43amalloyjustin_smith: (.log js/console "hi") macroexpands to (. js/console (log "hi")), so the advice to try switching between them can't be right
17:45justin_smithamalloy: my suggestion was differnet though, or maybe I misunderstand you
17:46cYmenswarthy: I suppose that was satiric, right?
17:47amalloy(. js/console log "hi") is exactly the same too, justin_smith. if you were suggesting something that isn't any one of those things, i can't tell what it was
17:47justin_smithok, I did misunderstand, thanks for clarifying
17:48brainproxysuppose an s-expr in namespace A invokes a macro in namespace-B, and in the form passed to the macro there is a symbol c/d
17:48cYmenswarthy: I take it back, it actually works I must have screwed something up when I tried that earlier. Thanks!
17:49brainproxywhen c is an alias per A, is it possible to resolve c/d to a var in the context of the macro
17:49swarthycYmen: order is important. (do) evaluates everything inside but only returns the last item. So if your (layout/common) wasn't last you would have gotten a blank page or maybe a 404
17:49TimMcbrainproxy: Then it will already have been expanded to my.namespace.ccc/d
17:50brainproxyTimMc: i find that is not the case
17:50brainproxybut the monkey wrench may be that that A is a cljs namespace while B is a clojure namespace
17:50TimMcOh, well, who knows then? :-P
17:51brainproxyif c is not an alias, I can get to the var in the manner I want, namely to see if it points at another macro
17:51brainproxybut it's when c is an alias, that I'm stuck
17:51TimMcOh wait, no, it's not already expanded -- that's done after macroexpansion happens.
17:52TimMcDoes resolve do it?
17:53jamiei_Any incanter pros resident this evening?
17:55TimMcbrainproxy: Calling resolve on the symbol seems to work.
17:59brainproxyTimMc: I found it wasn't working
17:59brainproxybut are both namespaces normal clj in your case?
18:14seangroveHrm, having a hard time getting the right call form to insert multiple rows in clojure.java.jdbc.sql/insert
18:16amalloyif both namespaces were clj-jvm, resolve would be the ticket. if A is cljs, god only knows
18:18`cbpseangrove: (insert! db :foos [:foo :bar] [1 1] [2 2] [3 3]..)
18:23seangrove`cbp: Looks like that works, was trying to use the new clojure.java.jdbc.sql/insert fn rather than the old insert! one, but maybe that's the problem
18:23seangroveThanks for the hint
18:55_scapein core.async what is (chan buffer-size) referencing? bytes?
18:58guns_scape: Queue size in items
18:58guns_scape: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/channels.clj#L31
18:59scapedang irc client pooped out
18:59gunsscape: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/channels.clj#L31 if you missed it
18:59scapethx, i did
19:14scapeguns ok, i got it. so specifying a buffer size of 0 holds 1 element, since it's like an array/queue; correct?
19:14gunsscape: I guess it depends on what you mean by "hold"
19:15scapeblocks :D
19:18gunsyes, IIRC (chan 0) acts like a TransferQueue
19:18gunsyou might want to test that
19:19scapeok
19:19scapethx
19:20scapesize 0 and no size specified seem to act the same.
19:20scapeif using <!! in a regular thread
19:23swarthyis dotimes roughly equivalent to (let [...] (do ...)) ?
19:24swarthyhmm, does not appear so.
19:25gunsscape: Did you want the producer thread to block after put?
19:27scapeI think I figured out what I was looking for. Basically I want to spin off a thread to do IO, then block while putting on a channel. in the main thread I want to periodically check the channel to see if the other thread is done, checking while not blocking itself.
19:27scapeguns: for what I am doing it's important for the main thread to not block but to also be able to basically do a callback to itself
19:28ambrosebsdanneu: do you want to add all non-nil-return calls to the checker?
19:28gunsscape: and you want a bounded queue for rate limiting I suppose
19:39danneuambrosebs: i wrote a macro to clean up my non-nil-return calls. i don't know yet if i'm just Doing It Wrong but it works for now
19:45danneuI have no java experience, but i imagine non-nil-return is necessary because looking up the java method indicate that it can return null
19:46danneuso that must be why the checker expects (U Thing nil), but it so happens that the java method never actually should be nil in my code, so i have a stack of non-nil-returns
19:46lynaghkping: hugod
19:47scapeguns: i do not want it to block the main thread.
19:48danneuambrosebs: https://www.refheap.com/20837 i couldnt seem to find a simple way to express this so i wrote a macro
19:48ambrosebsdanneu: yep that's the right way to do it
19:50ambrosebsdanneu: although it could be more hygienic. Use `non-nil-return
19:50mattmossIs one of these preferred, when expr1 could be nil? (or (expr1 ...) (expr2 ...)) vs. (if-let [v1 (expr1 ...)] v1 (expr2 ...))
19:51mattmossHmm, seems that's basically what "or" does.
19:54danneumattmoss: yeah, 'or' is clearer if that's your intention
20:06danneuIs (Class/forName "[B") the best we've got for defmethod byte-array dispatch
20:07danneuI'm still cruising with the first stackoverflow answer i found a year ago
20:07danneubut it seems to cause trouble with typed clojure
20:09richoI've got an app that starts a bunch of threads inside another clojure app via it's nrepl interface. The problem is that when I ctrl-c that container app, it doesn't die (because I'm calling starting a bunch of threads, then joining them, I think). Is there a better way to structure this/how can I make sure that ctrl-c kills all the threads?
20:10justin_smithricho: you could run (System/exit 0) rather than sending a control-c
20:10richoFrom the process that pokes at it's repl you mean? Right now I've got a script that lights up a dev environment in a bunch of tmux panes
20:11richoand you can kill everything by just mashing ctrl-c except the riemann instance, which refuses to die
20:11richobut if I don't do the "jack in and start threads" part it dies fine, so I'm pretty sure that's where the problem is
20:11justin_smithhow are you starting the threads?
20:12richojustin_smith: https://gist.github.com/7459554
20:12justin_smithif you are using agents, you may need to call shutdown-agents
20:12richoI think they're just java threads under the hood
20:12justin_smithyeah, you are just making Thread. calls, so shutdown-agents is not needed
20:13justin_smithare you doing any aggressive try/catch that may catch the control-c signal and keep going rather than exiting?
20:13richoI don't think there's a single try/catch in my entire codebas
20:13justin_smithaggressive as in catch on Exception or Throwable rather than a subclass
20:14richoand yeah, if I don't call that mainloop fn then riemann just dies on the ctrl-c so I'm like 99% sure that's where the issue lies (does that sound right?)
20:14richoSorry, pretty new to clojure and super new to the jvm
20:16justin_smithdo you have a repl open in that vm? if so, see if evaluating (System/exit 0) in that thread exits
20:17richoI can start one. One sec
20:17richoYeah, it does.
20:18richoI'm reading through riemann's source and the only signal I can see it explicitly handling is HUP, but I can duplicate what it does to co it and arrange for INT to call System/exit
20:18richoThanks, if this doesn't work out I'll probably be back with more questions soon
20:23richoActually, the other option is to just define exit! somewhere and document that you should poke at that from the repl
21:17muhooclojure.tools.trace saves my ass yet again
21:27bitemyappmuhoo: see? :)
21:29Raynesbitemyapp: Oh, he sees. He seems.
21:29Raynessees*
21:30RaynesI've been working with dictionaries so much today that I forgot how to spell 4 letter words.
22:25echo-areaMeta data prepending a macro calling form is discarded after the macro is expanded, right?
22:26echo-areaI.e. the meta data is set to the macro calling form
22:26echo-areaNot the result of the macro expansion
22:31TimMcecho-area: I seem to recall that the meta data is supposed to be attached, but that some macros ended up discarding it, and that this was considered a bug.
22:32S11001001TimMc: I went and found the place in Compiler.java that discards this, once; I don't think it would be hard to put it back
22:32echo-areaMeta data seems to be only hints to compiler with this respect
22:32S11001001TimMc: except for deciding what parts to put back
22:33echo-areaFor example, (let [m 4, n ^{:abc String} m])
22:33TimMchttp://dev.clojure.org/jira/browse/CLJ-865
22:34echo-areaHere meta data is attached to the symbol `m' read by the reader, not the value of `m' (which is of course not able to have meta data attached)
22:35echo-areaTimMc: Ah that's exactly what I was talking about :)
22:37echo-areaAnd it has a recent update (less than a month from now). Maybe it'll be merged into upstream in the next version :)
22:39echo-areaWait, the last comments indicate that it has already been merged
22:39echo-area... or not
22:53blris there a reason why domina's listen! doesn't take a map of events?
22:55blrthat would seem like a more natural api
23:02bitemyapp`cbp: DotA2?
23:02john2xhow do I let `lein repl` show a full stacktrace on exceptions?
23:03`cbpbitemyapp: sorry a little to tired >_<
23:03`cbptoo*
23:03bitemyapp`cbp: aw it's okay :)
23:03seangroveblr: Probably worthwhile to look at dommy and its listen methods
23:03`cbpbitemyapp: new revise version, pretty easy to compose the api into new helper fns
23:03`cbp:p
23:03clojurebotexcusez-moi
23:05blrseangrove: thanks, will have a look, have only looked at domina at this point
23:07bitemyapp`cbp: awesome. :)
23:08`cbpbitemyapp: now to figure out how to implement an efficient `let` query
23:08bitemyapp`cbp: that's recursive queries.
23:09bitemyapp`cbp: we'd probably want to ask Slava and crew at RethinkDB if they had any plans for that.
23:09`cbpoh
23:10bitemyapp`cbp: it wouldn't be substantially different than the "inefficient" version you're likely thinking of, but it would at least execute on their end instead.
23:11bitemyappand could be processed lazily.
23:11`cbplazyness is another issue
23:11bitemyapp`cbp: I take it we're not right now?
23:11seangroveSlava should be contributing to Clojure by now, what with his lispy nature
23:12bitemyappseangrove: oh you know him too?
23:12`cbpbitemyapp: nope
23:12bitemyappI guess I shouldn't be surprised.
23:12seangrovebitemyapp: Just a few mutual friends ;)
23:12bitemyapp`cbp: run-lazy? :P
23:12bitemyappseangrove: I knew of him through CL, then I talked to him about Revise awhile back.
23:12bitemyapphe doesn't really know who I am though.
23:13`cbpI am not entirely sure how to leverage the rdb api to implement that though
23:13`cbpsome sort of pagination?
23:13bitemyapp`cbp: oh yeah, pagination.
23:13bitemyapppossibly with chunking for efficiency :\
23:13bitemyappwhich...is...ow.
23:14`cbpsplit an insert/update/select into multiple queries hm
23:14`cbpmultiple runs i mean
23:14TimMcjohn2x: *e contains the last exception; (pst) will pretty-print the stack trace for *e
23:16john2xTimMc: Thanks. Hmm, the stacktrace isn't as helpful as I'd hoped.
23:16bitemyapp`cbp: if you're serious about that, it'd be a good time to think about how Clojure's laziness is implemented, especially chunking.
23:17john2xI'm getting "ClassCastException java.lang.String cannot be cast to clojure.lang.IPersistentCollection", apparently from a conj, but I'm not using conj anywhere in my code. And the stacktrace is all from clojure.core/ so I can't track down where it's going wrong
23:17`cbpheh yeah gotta read up on that
23:17bitemyappI wonder if pagination + a lazy-seq wrapper might work as a first pass though.
23:19swarthywhat is the best way to destructure the key/val pairs of a hash, while using map, reduce, etc.?
23:19swarthyI wrote an anon func to do it, but is there something more built-in?
23:19swarthyor idiomatic rather
23:20S11001001swarthy: depends on whether you're writing lambdas
23:21swarthy;(map <lambda-here> the-hash) is how I did it now. I was wondering if there was a better way, or a built-in function that does it better.
23:21swarthybecause I want to use the key and val for the return
23:22swarthyBasically taking a hash and making a table with hiccup.
23:29TimMcjohn2x: Sounds like you're passing in a string *somewhere* where you should be putting in a collection. I'm guessing you have some args swapped.
23:29TimMc&(into "foo" [1 2 3])
23:29lazybotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IPersistentCollection
23:30TimMc^ like that
23:31S11001001swarthy: it's perfectly fine to just use map on hashes, like, whatever
23:32S11001001swarthy: there isn't really anything to do to make it more convenient
23:36swarthyS11001001: cool thanks. I just wondered if there was a better way to use the key and val in the lambda instead of (fn [[key val]] ...) when you know you want both.
23:37swarthyS11001001: i'm probably just over thinking it, thanks for your help
23:48john2xTimMc: Thanks. I'll take a look