#clojure logs

2014-01-10

00:05amalloy##
00:05amalloyor a single & at the start of the message
00:05rplacaamalloy: why not write a macro to flip the let around? I don't think that would be too hard and it would be way more obvious to the reader what you were trying to do
00:05amalloyrplaca: i'm not excited about actually using this where construct, with the ->> trick or with a real macro
00:06amalloyjust surprised to note that clojure could easily fake where "out of the box"
00:06rplacaamalloy: there's always that. It does seem nice in Haskell, but I'm not sure it would work (mentally) in Clojure
00:07amalloyrplaca: the problem with a where macro in clojure is that syntactically it can't come in the same place it does in haskell
00:07amalloyyou have to write (with-where (+ x y) (where [x 1 y 2])) or something equally horrific
00:07Wild_CatHaskell's where is a very postfix-ish contruct
00:07rplacatrue, since you need a toket in the function position
00:07rplaca*token
00:07amalloyand ->> neatly fills that role
00:07arrdemdamnit. Do "we" have any details on Clojure/west yet?
00:08Wild_CatI think Clojure's standard "let" form is far cleaner.
00:08amalloyof course
00:08rplacaarrdem: last I heard, Alex was finalizing arrangements
00:08amalloyalthough haskell's works well in haskell
00:08rplacaamalloy: +1
00:08arrdemrplaca: awesome. we have a place and date.
00:08arrdem(inc rplaca)
00:08lazybot⇒ 1
00:08Wild_Catin Haskell though, where feels more natural than let.
00:09rplacaarrdem: I think it's going to be SF. That's what ALex told me last I asked him about it, but that was back around the conj
00:09rplacadunno the dates
00:09arrdemrplaca: yep.
00:09arrdemMarch 24->26
00:09rplacaahh, cool
00:10arrdemwhich means that I can apply to get funding from the Department to come out :D
00:10rplacaI was hoping we'd do Portland again, but I guess I can't complain too much about SF
00:17bitemyappWild_Cat: partly because it lets you say upfront what you're going to return, overall, then where lets you describe how that got put together.
00:19seancorfieldThe Palace Hotel is really nice - MongoSF was there in 2013
00:22logic_progdnolen: someone needs to write a core.async cookbook
00:22logic_progdnolen: of all the pattenrns that (1) are hell with callbacks and (2) have really neat core.async solutions via csp
00:24bbloomamalloy: thanks! that msg is more for dnolen
00:24amalloybbloom: i sent it to you because you're the one who committed the code
00:24amalloybut hey, if it's for him, let him know
00:24bbloomamalloy: really? i did?
00:25amalloybbloom: https://github.com/clojure/clojurescript/commit/af4ab91754d30f082b117b40c07ea94d0063c0d6
00:25bbloomamalloy: oh hey, i did.
00:25bbloomlook at that, lol
00:26bbloomamalloy: is there a ticket?
00:26amalloynot as far as i know
00:26bbloomi've been drinking & am gonna wonder away from my desk now, but i don't want your bug report to go missing :-P
00:26amalloyseangrove just pasted a stacktrace of breakage, and i tracked it down to this code for him
00:27bbloomamalloy: thanks
00:27bbloomamalloy: if you or seangrove can open a ticket, that would be awesome. sorry i can't be more help now. thanks!
00:28seangrovebbloom: Enjoy your drinking!
00:55ddellacostareally confused by this exception: Exception in thread "main" java.lang.IllegalAccessError: get-header does not exist, compiling:(not_modified.clj:1:1) <-- seems to be referring to ring.middleware.not-modified, which refers to ring.util.response/get-header. What could be causing this? Full exception: https://www.refheap.com/22750
00:58rplacaseancorfield: is ClojureWest going to be at the Palace or are you just saying it would be good there?
01:01TEttingerddellacosta, that's odd https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/response.clj it is defined right?
01:02seancorfieldrplaca: look at the clojurewest.org website
01:02seancorfieldit lists the hotel and dates
01:02ddellacostaTEttinger: yeah. I'm poking around lein reps now...think it's probably something in a specific profile that's conflicting...older version of ring maybe?
01:02seancorfieldoh, actually the website doesn't say... but alex's announcement on the mailing list did
01:02TEttingerhttps://github.com/ring-clojure/ring/commit/52c11854f6050a2a4a9261c6e77acf265b0b194e#diff-84b6775eb77642c1afe9b5745af47a2f
01:03TEttingerddellacosta, that commit, 10 months ago, added it
01:03ddellacostaTEttinger: huh, surprised it was even that recent
01:04TEttingerit's present in 1.2.0
01:05TEttinger(and everything newer)
01:05ddellacostaTEttinger: pooh, I figured it out...include from another private project of ours. Nevermind :-p
01:05ddellacostapooh -> ooh
01:05seancorfieldrplaca: here you go: https://groups.google.com/forum/#!topic/clojure/HaZVWRiDEAM ;; Clojure/West announcement
01:05ddellacostadamn spellcheck
01:06rplacaarrdem: did you see that post from seancorfield - that's the pointer you were looking for
01:07rplacaseancorfield: you're on the bleding edge there - I'm not keeing up with the list that well these days :)
01:07rplaca*bleeding, keeping
01:07rplacathanks!
01:07rplacaI like that choice, cause I can walk to it from my house.
01:08seancorfieldI can walk to BART and ride that to SF :)
01:08seancorfieldAnd it is a *lovely* venue!
01:09seancorfieldI'd submit a topic proposal but I'm already committed to creating two new presos for conferences in May / June :(
01:10rplacaseancorfield: I'll have to think about whether I've got something worth submitting
01:12xpikaThe function read-string reads a single form. Is there a core clojure function that reads multiple forms like those in a .clj file?
01:28sm0kehow does one writes a recursive macro?
01:29sm0kei am trying to write on with top level form as 1()
01:29sm0ke`() *
01:32sm0ke,(defmacro weird-macro [&body] `(~@body (weird-macro)))
01:32clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: body in this context, compiling:(NO_SOURCE_PATH:0:0)>
01:32sm0ke,(defmacro weird-macro [& body] `(~@body (weird-macro)))
01:32clojurebot#'sandbox/weird-macro
01:32sm0ke,(weird-macro (inc 1))
01:32clojurebot#<CompilerException java.lang.StackOverflowError, compiling:(NO_SOURCE_PATH:0:0)>
01:33sm0keoh did that worked!
01:46arrdemrplaca: thanks to insomnia I just did :D
02:52andyfbitemyapp: I saw in the logs a mention of a desire for eastwood to complain about :use
02:58bitemyappandyf: yes
02:59andyfI am guessing no warnings are desired for a use with :only, only for a use that sucks in the whole namespace?
03:06arrdemandyf: personally I would object to any use of (use) over (requrire), but silencing a linter with :only is I suppose reasonable.
03:07andyfarrdem: I'd prefer to warn about the most dangerous uses only, in hopes that people will avoid just turning off those warnings.
03:08andyfarrdem: You don't even do (;use clojure.test) in your test namespaces?
03:08arrdemandyf: nope. I actually sumitted a patch to the lein template which replaces that (use) :P
03:09arrdemonly useful patch I've got live anywhere but so be it.
03:09andyfarrdem: So you :require :refer [is] ?
03:09arrdemandyf: yep.
03:09arrdemandyf: occasionally I'll do a :refer :all if I know what I'm doing, but it's something I try to avoid.
03:14mark_ozhey guys, I'm having a bit of a problem with pulling a symbol from a map https://gist.github.com/markgandolfo/5adf492f5ad12d8af322
03:15mark_ozcan anyone lend some experience?
03:16arrdemmark_oz: that's not a map, that's a list containing a map.
03:16andyfTry (:title (first post)) ? Looks like post is a sequence of one map, from the parens around it
03:16arrdem^^ this
03:17mark_ozthanks guys, that worked
03:58bitemyappandyf: just suggest rewriting use with :only to require.
03:58andyfbecause?
03:59bitemyappandyf: the safe thing is to expect use to get deprecate.d
03:59bitemyappit's not orthogonal and people should phase it out of their code.
03:59bitemyappit sets a very bad default.
03:59bitemyappI'd do the same to Haskell's import if I had my druthers.
03:59bitemyappsadly, they get away with it because they have an exceptional type system and compiler.
04:01andyfI'll consider it. Just working through the surprisingly-many cases of a use without :only right now. Trying to recognize them all.
04:02andyfAlthough I should simplify my life by assuming Clojure itself hasn't complained about it.
04:02arrdembitemyapp: well... all done. ish. http://arrdem.com/2014/01/10/Batbridge.html
04:25noncomwhen using tools.namespace, i cannot predict its behavior. i have a project in "checkouts" of lein, and tools.namespace seem to fail finding the namespaces of the referred project in an arbitrary manner
04:26noncomif i manually load the ns that cannot be found, it then works
04:27noncomhow do i make the tools.namespace/refresh to find all the files?
04:45rurumate,"hi"
04:45clojurebot"hi"
04:47arcatan"hi"
04:59mullr:salutations
05:06ddellacostamullr: hello.
05:11sverihi, i am trying to use the c2 (http://keminglabs.com/c2/) library and like to draw a polyline, however, i have not found an example or something similiar, how would i do that with c2? any ideas?
06:00Arafangionit isn't that hard to learn most languages though.
06:00Arafangionif i needed to work in a project, i would learn the language - might not be elegant at first but it isnt a big deal.
06:24AeroNotixhas anyone used Authorize.Net from clojure and/or is there already a library for it?
06:25fizrukhello guys! what's the easiest way (with clj-time) to check whether to dates are separated by midnight (e.g. 31 Dec 2013 23:59:59 and 01 Jan 2014 00:00:01)?
06:29augustlAeroNotix: my first action would be to google for a Java lib for that
06:29AeroNotixaugustl: there is. They provide it.
06:29augustlAeroNotix: and possibly just write that part in Java if that for some reason is less work
06:29AeroNotixaugustl: no, java is never Less Work
06:29augustlperhaps they have a finished servlet you can just tack on to your exiting servlet, for handling the callbacks and such
06:30AeroNotixI've been looking at the docs. It's just classes which map to their SOAP API
06:30AeroNotixI just wanted to know if there was a better way.
06:31augustlfizruk: as in if they represent different days in a given time zone?
06:31augustlfizruk: or that they are adjacent days in a given time zone?
06:32fizrukaugustl: different days in a given time zone, not always adjacent
06:36fizrukaugustl: I wish I could truncate datetime to date, can I do that?
07:36jtoyis it possible to do this: from ns A include ns B , then if other namespaces use A, they can use the methods from ns B ?
07:38jballanc_jtoy: should be able to do that with anything you "use" or ":refer"
07:40otfromDoes anyone have an example of integrating friend and liberator?
07:40otfromI know sritchie has been working on some stuff
08:00sverihi, i am trying to use the c2 (http://keminglabs.com/c2/) library and like to draw a polyline, however, i have not found an example or something similiar, how would i do that with c2? any ideas?
08:25rurumateI want to write this with swiss-arrows but it fails: (-<> 2 (+ 4 (inc <>)))
08:25rurumatethis works: (-<> 2 (+ 4 <>))
08:26rurumateWhy can only use <> in the top level of expressions? Is there an alternative macro where the diamond can appear in nested forms?
08:26fredyrholy threading batman
08:27mdrogalisLooked at this before I had my coffee. Brain broken.
08:27fredyrhaven't seen swiss-arrows before
08:31fredyrthe doc string says top-level insertion of x in place of single
08:31fredyrpositional '<>' symbol
08:36edbondfizruk, try (to-date) and compare
08:37fizrukedbond: thanks!
08:45edbondfizruk, I was wrong, you need to extract year, month, date and compare them
08:45edbond(year (fmt/parse (fmt/formatter "yyyy-MM-dd HH:mm:ss") "2013-12-31 23:59:59")) ;; 2013
08:47edbond((juxt year month day) d1) ;; [2013 12 31]
08:48fizrukfortunately, one of two dates I deal with is (now), so I just used (after? (today-at-midnight) dt)
08:48fizruknevertheless, it seems that clj-time lacks date truncation functions
08:51DerGuteMoritzohai edbond :-)
08:51edbondDerGuteMoritz, hello :)
08:52DerGuteMoritzlong time no see :-)
09:02ro_stdnolen: what could prevent cljsbuild :none incremental builds? we're getting 10s a build even with a single change to a single ns
09:02ro_stwhat's the best way to dig into why it's so slow?
09:03ro_stcljs "0.0-2138" / cljsbuild "1.0.1"
09:05jcromartiein Light Table, where can I see errors related to connections?
09:05jcromartiei.e. I am trying to connect to a project but it fails silently
09:08CookedGryphonjcromartie: there's a little red box near the bottom of the screen with a number in it (the number of errors*
09:08CookedGryphonclick that to bring up the console
09:12john2xhello. is there a leiningen plugin for colored input/output for the repl?
09:12jcromartiethe console doesn't show anything when I add a connection to a project.clj
09:13jcromartieit is just silent, like it isn't even trying
09:13jcromartiedoes it just not work?
09:13jcromartieor do I misunderstand what "add connection" does?
09:13jcromartieI'd expect it to open a REPL
09:15CookedGryphonjcromartie: try pressing ctrl + enter in a file
09:15CookedGryphoni've not played with it much myself, but i remember being a little confused by that, but evaluating something in a file loaded it automatically
09:15jcromartiehm, so it doesn't connect until you Ctrl + Enter
09:17jcromartiebut, yeah, it's working for my app! yay
09:17jcromartieI am still a fan of Emacs with Cider
09:18jcromartiejust because it's familiar
09:18CookedGryphoni haven't even taken the time to move from nrepl yet
09:18ro_sti'm happy to wait 6 months for the community to build LT up
09:18CookedGryphontoo much work to do to be faffing around with my setu
09:18CookedGryphonsetup*
09:18ro_stlosing magit is going to be hard to deal with
09:19CookedGryphonLT does look promising though
09:19ro_stvery!
09:19CookedGryphonbeing able to write plugins in clojure rather than elisp opens up a *lot* of avenues
09:19jcromartie:P
09:19CookedGryphonso many things I've wanted my editor to do but got fed up of elisp
09:19jcromartieI see that there's a paredit plugin and commands, but no default keybindings?
09:19ro_sti feel like i've paid my school fees for emacs now
09:20ro_stdid the trial-by-fire of learning the paredits binds
09:20CookedGryphonro_st: you can move those all over to light table!
09:20CookedGryphonin theory, I haven't managed to get the emacs bindings to work yet
09:20ro_stthe paredit in LT is not the paredit that's in emacs
09:20jcromartieno
09:21ro_stsome stuff is there, but no ways is there all of it
09:21CookedGryphonro_st: so make them match, the keybinding action stuff is so so easy compared to emacs
09:21CookedGryphonyou can just add stuff as you miss it
09:21ro_stlike you, i have far too much work to do
09:21CookedGryphonbut yeah, I'm going to give it another release or two
09:21ro_stheck, we only just moved to cljsbuild 1.0.1 this week
09:23ro_sti experienced the warm glow that is working cljs sourcemaps today. stepping breakpoints in cljs in the browser. man. so awesome
09:23AeroNotixHow do I use -> macros on mutable java objects?
09:23AeroNotixI.e. a (.Method Object) -> nil
09:23ro_stAeroNotix: (.. thing .call .call)
09:23AeroNotixtrying
09:23hyPiRionAeroNotix: usually you'd use doto instead
09:23AeroNotixI tried this
09:23AeroNotixoh I will look at doto, as well.
09:23ro_stclojure.org/java_interop
09:23AeroNotix Cheers!
09:23hyPiRion,(doto (java.util.ArrayList.) (.add 1) (.add 2))
09:23clojurebot[1 2]
09:24rukorro_st: i had that when i had local macros. When i moved the macros to a library in checkouts i got back sub second compilation. Not saying it's it but just sharing my experience
09:25AeroNotix,(doto (Calendar/getInstance) (.add Calendar/DAY_OF_YEAR -10) (.getTime))
09:25clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: Calendar, compiling:(NO_SOURCE_PATH:0:0)>
09:25AeroNotixdero
09:25ro_strukor: we only have macros in our checkouts
09:26ro_stpure cljs in the main project
09:26rukorro_st: interesting then
09:26ro_stweird thing is, on 1.7.0_45 on mac it's fine - 0.5s. i have ubuntu users on 1.7.0_25 getting 10s
09:26ro_stcuriouser and curiouser
09:27ro_stthey're not getting incremental, basically
09:28rukorwould seem so.
09:28rukorclean, then start over?
09:29ro_stthat was our first port of call :-) lein clean, lein cljsbuild clean
09:55expezAfter doing reloading code and running tests with clojure-test-mode the tests starts to get duplicated instead of updated, why does this happen?
10:08ro_strukor, dnolen: the issue has been found and resolved https://github.com/emezeske/lein-cljsbuild/issues/281
10:19rukorro_st: thanks
10:40CookedGryphonI think I'm getting weird bugs trying to combine core.match with core.async
10:40gfredericksexpez: did you rename a test?
10:41CookedGryphonif i do a match inside a go block, I always seem to end up with only the first match working and everything else falling through to the else
10:41CookedGryphontake it out of the go block and it works as expected
10:42fizrukis there a map-like function for persistent Maps which returns new persistent Map? e.g. (my-map + {1 2 3 4}) => {1 3 3 7}
10:42fizrukI'd like to map values (but use key when mapping)
10:43sw1nnsritchie: I'm looking at friend + liberator integration and I found your PR on liberator, Where is friend/unauthorized! - is that your function?
10:45DerGuteMoritzfizruk: (into {} (map (fn [[k v]] [k (+ k v)]) {1 2 3 4})) is how you'd usually do it
10:45hyPiRionfizruk: just ##(into {} (for [[k v] {1 2 3 4}] [k (+ k v)]))
10:45lazybotclojure.lang.ArityException: Wrong number of args (3) passed to: core$for
10:45sritchiesw1nn: yeah, I was writing up a post - let me push the example repo I'm making
10:45DerGuteMoritzhmhm, for
10:46fizruk,(#(zipmap (keys %) (map (partial apply +) %)) {1 2 3 4})
10:46clojurebot{3 7, 1 3}
10:46sw1nnsritchie: great, thanks
10:46DerGuteMoritzugh :-)
10:46sritchiehttps://github.com/sritchie/liberator-friend/blob/master/src/liberator_friend/core.clj
10:47sritchieso, the routes + stuff for hte post aren't in place yet,
10:47sritchiesw1nn: but here's the applied friend middleware with basic auth,
10:47sritchiehttps://github.com/sritchie/liberator-friend/blob/master/src/liberator_friend/middleware/auth.clj
10:47fizrukDerGuteMoritz: hyPiRion: thanks!
10:47sritchieand here are the resource helpers:
10:47sritchiesw1nn: https://github.com/sritchie/liberator-friend/blob/master/src/liberator_friend/resources.clj
10:47DerGuteMoritzfizruk: yw!
10:47DerGuteMoritzreduce-kv could also be worth trying
10:48DerGuteMoritz,(reduce-kv (fn [r k v] (assoc r k (+ k v))) {} {1 2 3 4})
10:48clojurebot{3 7, 1 3}
10:49sw1nnsritchie: Thats fantastic, just what I was looking for, thanks again.
10:49sritchiesw1nn: so making a resource with :base authenticated-base will get you going
10:49sritchieI think there's a bug or two in here with pass the context vs request...
10:49sritchieI have a busted level of unwrapping at one spot
10:50sritchiesw1nn: lmk how it goes! Comments on the proj would be great if you have suggestions
10:50sritchiemore coming on that soon
10:54zerokarmaleftsritchie: nice, I'm working on a project with liberator+friend too...I may have some questions/comments for you later
10:55sritchiefor sure
10:55sritchieI'm traveling today, so if you guys want to make issues on that project that'd be great
10:55sritchieI'll get that post out sunday or monday, probably
10:56gfredericksis there an option in recent cheshire to turn off the top-level-lazy-seq thing?
10:57dakronegfredericks: yes, there's a parse-strict option
10:57TimMcgfredericks: something somethign strict
10:57jcromartieso while clojure.tools.namespace is nice, I've just decided to add a call to a custom (unmap-all) at the top of my namespaces
10:57jcromartieyes it breaks defonce
10:58gfredericksdakrone: gotcha looks like 5.3; will upgrade
11:16boblarrickIs there a way to do something like `(map #(apply * 400 %) [1 [2 (/ 9 8)]])` that would return (400 900) ?
11:19jcromartieboblarrick: wat...
11:20hyPiRion,(map #(apply * 400 (cond-> % (not (sequential? %)) vector)) [1 [2 (/ 9 8)]])
11:20clojurebot(400 900N)
11:21hyPiRionprobably not the best one though
11:21justin_smith,(map #(apply * 400 %) [[1] [2 (/ 9 8)]])
11:21clojurebot(400 900N)
11:21jcromartieI see
11:22justin_smithjcromartie: do you really need the input to be sometimes number sometimes sequential?
11:22jcromartiejcromartie: boblarrick was asking
11:23justin_smithoh, oops
11:23justin_smithboblarrick: do you really need the input to sometimes be a number and sometimes sequential?
11:24boblarrick1justin_smith: Yeah I was hoping for a way that didn't use cond, and that could handle sometimes number, sometimes seq
11:25gfredericksoh I didn't just want strict, I wanted a vector
11:26gfrederickshmm
11:26justin_smith,(map #(apply * 400 (flatten %&)) [1 [2 (/ 9 8)]]) ; I hate myself for this, but it works
11:26clojurebot(400 900N)
11:27justin_smiththat code tastes like sawdust :(
11:27clgvdoes leiningen's :global-var also work for non clojure.core variables?
11:38zerokarmaleftboblarrick1: I'd take that as a code smell...perhaps whatever is generating the sequence to map over can supply a seq that's uniform
11:39zerokarmalefti.e. a single number is wrapped in a vector
11:40zerokarmaleftthen you get something clean like what justin_smith first suggested
11:40zerokarmaleft,(map #(apply * 400 %) [[1] [2 (/ 9 8)]])
11:40clojurebot(400 900N)
11:43justin_smithzerokarmaleft: notice that was exactly my first suggestion
11:43justin_smithand noting flatten makes it do what he wants: ~flatten
11:43justin_smitherr
11:43justin_smith~flatten
11:43clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
11:44ddima_smart bot
11:44stuartsierra~botsnack
11:44clojurebotThanks, but I prefer chocolate
11:44stuartsierra:)
11:44gfrederickshas anybody seen some nrepl middleware that wraps everything in (time ...)?
11:44gfredericksor know of a similarly structured middleware I could blindly mimick?
11:46stuartsierraxeqi: Pushed fix for DJSON-13, if you want to give it a try.
11:46zerokarmaleftjustin_smith: yes, I see that...just wanted to reinforce that "flatten" is usually a bad idea :)
11:48boblarrick1Thanks al
11:48boblarrick1*all
11:49justin_smithzerokarmaleft: but that is why I suggested flatten - the root problem is a design problem, the same design problem that leads to using flatten
11:50justin_smithflatten being a symptom of that problem, not solution, mind you
11:52boblarrick1 /shrug. Who knows where data comes from, and how much control one has over it.
12:00justin_smithboblarrick1: would you a) write a version of multiply that checked if args were strings and parsed them as numbers before multiplying, or b) write a preprocessor that validated and coerced input when received? No need to complect handling input with processing it.
12:05jcromartiecan anybody help me understand why this works the way it does, and how to avoid it? https://gist.github.com/jcromartie/b63a93e0845603636f9e
12:06jcromartiesorry, updated
12:06boblarrick1justin_smith: Of course I'd us a preprocessor, unless I was getting data from somewhere else and playing around with overtone in a repl and just wanted a oneliner ;)
12:07justin_smithjcromartie: my hunch is that defn creates a var, or resets it if it exists
12:07justin_smithjcromartie: and g does not get f as a name of a var, but the var f resolves to
12:08justin_smithjcromartie: so if the initial var exists, it picks up the new value, but after the remapping, f is a different var (just happening to have the same name) so it does not affect g when you set its value
12:08justin_smithjust guessing though
12:08Bronsajcromartie: http://sprunge.us/GYMF
12:09Bronsajustin_smith: that's almost right
12:09jcromartieBronsa, justin_smith, seems to be the case
12:09jcromartiethanks
12:09justin_smithBronsa: cool, that seems to back up my hunch
12:09justin_smithBronsa: about the almost, please enlighten me
12:09jcromartieso, is there a way to remove stale vars while avoiding this issue?
12:09Bronsajustin_smith: it's not defn that creates||resets, it's def
12:10justin_smithBronsa: right, because defn is just a macro over def, right?
12:10Bronsasure
12:11justin_smithwell, clearly not *just*, now that I see the source
12:11stuartsierradata.json 0.2.4 is in the can now.
12:12Bronsajcromartie: not really, the closest you can get is to unbind the var (.unbindRoot #'the-var) instead of ns-unmapping it
12:12jcromartieso if I do this: (doseq [sym (keys (ns-interns *ns*))] (ns-unmap *ns* sym))
12:13jcromartieI want to specifically avoid the issues where renaming a function during interactive development leads to floating references hanging around
12:13jcromartieand I'd love to use clojure.tools.namespace but it blows up on my with my AOT needs
12:13jcromartieI guess the answer is "be careful"
12:14justin_smithjcromartie: I wonder about maybe a function that parses a namespace file as edn, and also looks at the ns-publics of the same namespace, and returns the ns-publics not reflected by the forms in said edn?
12:15stuartsierrajcromartie: Don't know if this is an option for your use case, but if you can separate your AOT-compiled code into another project, tools.namespace will work.
12:15justin_smithwhich more or less would give you the floating stuff (unless you were using higher level trickery to create vars)
12:16jcromartiemaybe I could redefine def :)
12:16jcromartieto update a counter
12:16jcromartieoh god what have I done
12:17technomancygen-class inside a fedonce
12:17technomancydefonce
12:18pandeirowhere does stdout end up going when using lein repl :headless ...?
12:19technomancypandeiro: "stdout" is ambigious
12:19pandeirotechnomancy: i'm using pedestal and when i do `lein run`, services log requests to the terminal's stdout; when i do `lein repl :headless` etc, they don't
12:19technomancySystem/out will go wherever the process is started
12:19justin_smithtechnomancy: yeah, I have been tempted to use defonce for side effects like that, maybe it calls for a "do-once" macro
12:20technomancythe root binding of *out* will be the same
12:20technomancyout of th ebox at least
12:20stuartsierra`gen-class` has no effect when not AOT-compiling.
12:20technomancypedestal might change it
12:20technomancythe thread-local binding of *out* could be anything the client wants it to be
12:20pandeirotechnomancy: i am using foreman to start a bunch of services in one terminal, maybe that is at play... but when i use foreman with lein run, i see output
12:21technomancyremove variables until the problem can be isolated
12:21pandeiroyeah ok
12:24hansel-hanany library name that includes a substring of "clojure" is an instant classic imo. can't really go wrong with that.
12:25hansel-hani'm lovin "Cloact", React for Clojurescript
12:25michaniskinclojacked
12:25michaniskindisregard that came out wrong :)
12:25michaniskini mean clojact
12:25hansel-hanoh, nice
12:26hansel-hanthe impromptu brilliance of this community keeps me coming back
12:26michaniskini guess probably not good to have "jacked" in the name, at least in the US
12:26hansel-hannah, dude. i always tell people at the gym how jacked i am
12:27michaniskinmy barber shaves jacks every day
12:27michaniskindude is a hacker extraordinaire
12:27andyfBronsa: Any thoughts on alpha releases of tools.analyzer(.jvm) libs? :-)
12:28tbaldridgeBronsa: I'll also be asking for this sometime in the next few months, I'm re-writing core.async to use tools.analyzer as we speak
12:29Bronsaok, I guess a 0.1.0-alpha1 is in the way then
12:30hyPiRionyay
12:30stuartsierrajava.classpath 0.2.2 is on the way.
12:30hyPiRionI need to use tools.analyzer for some project of mine, but really want a stable release. So this is good
12:31andyfBronsa: excellent. Eastwood still has some sharp edges, and I'm sure there are problems I don't know about yet, but it seems about ready to have a few more people besides us run it through the grinder
12:32jcromartiewoah… Chrome's view-source gives some serious nondeterministic results
12:32jcromartieweird
12:32Bronsaright, I guess having people actually use it will probably help us find/fix more bugs :)
12:32bbloomBronsa: i apologize in advance for asking this question, but ... how hard would it be to add XML literals to the reader?
12:33bbloomBronsa: b/c apparently "looks like HTML" is an important requirement for some people, lol
12:33Bronsastuartsierra: t.a.j depends on t.a, does hudson automatically update the t.a version in t.a.j pom.xml or sohuld I do it manually myself?
12:33jonasenbbloom: :)
12:33stuartsierraBronsa: No, dependency version numbers are not updated automatically.
12:33Bronsabbloom: ugh. there's the issue of < > and friends being clojure.core functions
12:33Bronsastuartsierra: ok, thanks
12:34stuartsierraBronsa: you're welcome
12:34Bronsabbloom: I can try and give you a patch if you're *really* sure you mean it
12:35bbloomBronsa: lol i don't want it
12:35jonasenbbloom: you could do a JSX transformation and translate <foo></foo> into (foo) or [:foo]
12:35bbloomBronsa: i'm not personally interested in such silliness, since HTML is an abomination for UI components anyway
12:35Bronsa*phew*
12:35bbloomjonasen: yeah, that's basically the idea
12:35bbloomif it was just hilariously easy, i'd want it for the sake of a joke tho :-P
12:36bbloomif it was like "i can hack that out in ~20 min w/ low quality w/ some shitty regexes" i'd enjoy that, but that's the extent of my request
12:39andyfBronsa: Oh, one question on top level do forms. Does Clojure treat a do *inside* of a top level do the same as the top level do, i.e. analyze and evaluate its forms one at a time?
12:40technomancypretty sure it's just one level
12:40Bronsaandyf: I'm not really sure about that, let me check
12:40S11001001I think it's recursive
12:41Bronsait *is* one level, but I think clojure transforms (do (do foo bar)) into (do foo bar) somewhere
12:41apetrescWhat's the most mature parser-generator for Clojure? Like, to generate a parser for some CFG/PEG?
12:42tbaldridgeapetresc: I've heard instaparse is good
12:42apetrescI'm aware of fnparse but it doesn't look like it's seen any activity for ~3 years
12:42apetresctbaldridge, instaparse, thanks, I'll look into it :)
12:43apetrescOh neat, it looks perfect. Thanks again, tbaldridge!
12:43jcromartie"Can't change/establish root binding of: *print-length* with set" ??? like hell I can't
12:43hyPiRionapetresc: yeah, instaparse is the best
12:43justin_smithjcromartie: maybe you need binding or alter-var-root ?
12:44jcromartie,(set! *print-length* 100)
12:44clojurebot100
12:44jcromartieI can have this in a file when I recompile it with C-k, but not when it's loaded when starting up the project
12:44tbaldridgejcromartie: the var doesn't have a root. set it with alter-var-root
12:45jcromartiewhy does it work after the facT?
12:45jcromartieafter the REPL starts up, that is
12:45technomancythe repl binds it
12:45tbaldridgejcromartie: stuart just talked me through that one the other day. You can't do set! on a var that is unbound. The REPL goes and sets roots for a ton of stuff. That doesn't happen when you app is run outside of the repl.
12:46jcromartieah ha
12:46tbaldridgeI dug into Var.java for awhile at it does make sense, but yeah, it's a pain.
12:46jcromartieis there any kind of hook for after the REPL starts up, particularly in a user.clj namespace?
12:46tbaldridge*and it
12:47amalloy$google lein sample project.clj
12:47lazybot[Leiningen's sample project.clj - GitHub] https://github.com/technomancy/leiningen/blob/master/sample.project.clj
12:47amalloyjcromartie: iirc it's called something like :repl-init
12:47tbaldridgeI'd just wrap your app entry point in a (binding[])
12:48jcromartiethanks amalloy
12:49Bronsabbloom: http://sprunge.us/GbOX?diff
12:49bbloomBronsa: ha! awesome. does that really work?
12:50Bronsawait, it has a bug.
12:50bbloomBronsa: too bad the #< dispatch macro is already used for "unreadable"
12:50bbloomwhich i guess is accurate, since XML is unreadable... ZING!
12:50andyfBronsa: I test eval form seems to confirm that a do inside of a top level do somehow causes its subforms to be analyzed and evaluated before the next subform
12:51Bronsabbloom: http://sprunge.us/HIKX?clj here
12:51Bronsas/clj/diff
12:53Bronsaandyf: yeah, looks like so (line 5733 of Compiler.java)
12:54Bronsaso it does (do (do 1 2) 3 4) => (do 1 2 3 4)
12:59amalloyandyf: a top-level (do a b) is treated as if it were the two top-level forms a and b. naturally if a or b is a do, the same thing happens "recursively"
12:59andyfBronsa: amalloy: technomany: I can't navigate Clojure compiler source as fast as Bronsa, but this REPL interaction confirms his findings https://gist.github.com/jafingerhut/8359201
13:01amalloyandyf: you've doubtless already written code many times that would break if things didn't work this way
13:02andyfamalloy: If I did, I wasn't aware of it :-)
13:02amalloywell, i was thinking of stuff that macroexpands to (do (do (do (defn ...)))) or whatever, but i guess if there aren't any "backreferences" in there it would work either way
13:03bbloomBronsa: ok now dnolen needs to write a blog post to be like "what? you want HTML? fine. you bastards"
13:03andyfOK, well now I know. Looks like I need to go remove the max-1-deep limitation I coded into the part of Eastwood that handles this case.
13:03bacon1989Hi, I was wondering how easy it would be to jump into clojure with clojurescript? I have very little lisp experience other than emacslisp
13:05dnolenbbloom: Bronsa: heh that is pretty cool, but I really am glad to remain clear of such trivial decisions
13:05justin_smithbacon1989: the toolchain with clojurescript is still a little janky in my experience - it works but the dev environment / workflow is weird (to me at least)
13:05justin_smiththat said, clojurescript is great once you have it compiling / running in the browser
13:06seancribbsdnolen: ohai, you going to stick around?
13:06dnolenseancribbs: yep
13:06justin_smithbacon1989: the jvm version is much easier to fire up and experiment with and learn in
13:06seancribbsdnolen: cool, midday meetings and things then I'll ask you about Om stuff
13:07S11001001bacon1989: there's a little more setup than emacs lisp, unless you're non-FP and are going to hold onto anti-FP biases. I can't say about clojurescript, though. First tip: ignore clojure install, go to https://github.com/technomancy/leiningen#installation and https://github.com/clojure-emacs/cider#installation , that's what you need to start.
13:07S11001001bacon1989: as you mentioned elisp I assume your editor of choice is emacs.
13:08dnolenbacon1989: I think worth learning Clojure first, ClojureScript is not significantly different and the tooling is admittedly not as nice.
13:08dnolenbacon1989: doing ClojureScript in Light Table is the best experience I've seen so far
13:11rasmustobacon1989: doing clojure in lighttable is easy too
13:12bacon1989that's a lot of info, thanks a lot
13:12bacon1989I already have clojure running cider on emacs with leinigen
13:12bacon1989The only web development i've done though, is PHP and Python
13:13bacon1989i'm kind of wondering how long it could take for someone like myself to pick up clojure and write meaningful application?
13:13bacon1989I guess it would also depend on my dedication, maybe I shouldn't jump into it and use it in my next project 'just yet'
13:13rasmustodepends on your definition of "meaningful"
13:14rasmustobacon1989: I'd definitely recommend playing around with 4clojure and project euler before you try to build something with it, just to get language familiarity
13:15rasmustoalso, clojure programming (o'reilly) and the joy of clojure are good references
13:26justin_smithbacon1989: yeah, seconding rasmusto, common mistake for people coming from an algol-family language is to just jump in not really understanding clojure syntax/semantics, and 4clojure / clojure koans / euler will help prevent the tiny newbie mistakes from turning into a frustrating mess in a real project
13:26Bronsaandyf: hiredman tbaldridge t.a/t.a.j 0.1.0-alpha1 on their way to maven
13:26hiredmanneato
13:27andyfBronsa: If you are at Clojure/West, I owe you a beer :-)
13:28Bronsaandyf: eh, I could only wish I was. Italy is somewhat far :)
13:29Bronsaduh. s/hiredman/hyPiRion
13:30hiredmanhey, I care
13:31hyPiRionBronsa: yay
13:32muhoowhy is alter not alter!, or why isn't swap! swap ?
13:32technomancymuhoo: ! kind of half-heartedly means "unsafe in a transaction"
13:33justin_smithand alter only works in a transaction
13:36muhoomakes sense, thanks
13:38TimMctechnomancy: I'm going to start referring to Java! instead of Java
13:38technomancyhehe
13:38TimMcDownside: People will think I am excited about Java.
13:38technomancyor a yahoo! employee?
13:38TimMcha
13:39amalloydangit technomancy, too fast for me
13:40TimMctechnomancy: Wait, is that that keyboard you have to solder together?
13:40technomancyyeah
13:41technomancyit is The Best
13:41technomancyhttps://secure.flickr.com/photos/technomancy/11437911574/
13:41amalloyTimMc: technomancy's POV is that every keyboard is the one you have to solder together, but people just aren't as aware of it
13:42technomancyI'm not hard-core like thisg uy though: https://secure.flickr.com/photos/obra/8197649629/
13:43TimMcamalloy: Yeah, yeah. :-P
13:43TimMcI meant "you", not "you".
13:43technomancyhe couldn't even wait for the circuit board
13:44TimMctechnomancy: That first picture is one of the most hipster things I have ever seen. (Note: "Hipster" not used in a derogatory fashion here.)
13:45rasmustoI think its the scarf that really brings the picture together
13:45hiredmanI dunno, technomancy often wears a scarf, that is pretty hipster
13:45rasmusto(inc hiredman)
13:45lazybot⇒ 33
13:46bacon1989thank you rasmusto and justin_smith, I got lost in some code
13:46bacon1989I think I might pick up the oreilly book and just practise with it at first
13:46rasmustobacon1989: http://www.4clojure.com/ until you have the book :)
13:47justin_smithbacon1989: try some of 4clojure in the browser too - but note that numeric order is not difficulty/knowledge order
13:47justin_smithjynx
13:47technomancyTimMc: someone referred to it as "fashioning my very own majestic hand chariots" which is maybe my new favourite phrase
13:47TEttingerhey I had a beard before it was hip. I'm a neckbeard grognard, not a hipster!
13:48seubertis there a way to reset my 4clojure account
13:48seuberti did a bunch of exercises a year or so ago and was just going to restart
13:48TEttingerseubert, did you submit a password as an answer? haha
13:48seubertno haha
13:48justin_smithyou could just make a new one?
13:49hansel-hanif you started a website today, would yall use example.com or www.example.com?
13:49seubertjustin_smith: gotta dig up an email to use then i guess :V
13:49seuberthaha both of my usual emails are already used
13:49seuberti must have gone through this process before
13:49technomancyhansel-han: www-less looks nicer, but it's a lot less flexible if you need to make changes due to a ddos
13:50hansel-hanevery once in a while, i read a discussion where `www` provides benefits, but i can't tell how esoteric or useful the benefits are
13:50technomancyhansel-han: https://devcenter.heroku.com/articles/apex-domains
13:50hansel-hantechnomancy: if the extent of my response to handling a ddos was to utilize cloudflare, would i care?
13:50hansel-hani'll read that, thanks
13:51justin_smithhansel-han: if you own foo.com, you also control www.foo.com automatically
13:52hansel-hanjustin_smith: right. half the sites i own redirect www->naked, the other half naked->www. i'm launching a fresh website and trying to be deliberate about it for once
13:59nDuff...there are some fairly common practices that violate the letter of the RFC when done with naked domains
13:59nDuffthough why we're having this discussion in #clojure...
14:00stompyjdoes anyone have any experience with deploying clojure apps to vagrant?
14:03jcromartiestompyj: a little
14:03jcromartiegenerally with "lein run"
14:03jcromartieand a good main
14:04stompyjjcromartie: but the step before that, do you just check out master from git? etc?
14:04TimMctechnomancy: That is a fantastic phrase.
14:05stompyjcurrently I'm using chef+capistrano
14:05stompyjwondering if I should just move to ansible
14:07jcromartie… why would ansible beat chef + capistrano
14:07jcromartiewhen you can just push an uberjar and run it?
14:08jcromartieeither check out source and lein run, or package the uberjar and push that
14:08jcromartieactually I prefer the uberjar for most cases
14:08stompyjhmmmm, actually, pushing the uberjar is extremely interesting
14:08stompyjI just don't want to use capistrano, and ansible (supposedly) can handle deploys
14:09stompyjdeploying to production is so easy with beanstalk or heroku
14:09stompyjwhen I went to deploy to vagrant I wasn't sure what the idiomatic-esque solution was
14:09technomancyare you talking about vagrant in production or what?
14:11stompyjno, we use vagrant as a staging like environment
14:12stompyjthat was any developer can just "vagrant up" a service
14:12stompyjinstead of having to worry about dependencies on their local box
14:12technomancyyeah, the uberjar is a great way to do that
14:12stompyjyeah
14:12stompyjthat sounds like the move
14:13stompyjI keep forgetting that its all java under the hood, so .jar and .war files are in play
14:13mdrogalisStu Halloway is on the Youtube's live right now
14:13tbaldridgehttps://www.youtube.com/watch?v=VD9UCfQohQE
14:13technomancyyou'll need to figure out $JVM_OPTS yourself from wherever the rest of your config is coming from
14:14stompyjtechnomancy: makes sense, thanks!
14:14stompyjI saw Rich give a talk on datomic here in NY a couple of months ago, itching to use it in a project
14:15randomenduserI'm having troubles getting https://github.com/cemerick/austin up and running. Is that the recommended way to get a browser repl these days?
14:16TimMcstompyj: So if you have a bunch of services you need to develop against, do you load the vagrant instances locally, or on a remote machine?
14:16seancribbsdnolen: ping
14:17stompyjTimMc: right now, locally. as I'm sure you're thinking, this is problematic if you have a ton of services. this project I'm doing now only has 3
14:17stompyjso it's not so bad
14:17cemerickrandomenduser: I certainly believe so. If you follow the readme and/or the browser-connected application sample that it links to, you should be good. If not, file an issue.
14:18randomendusercemerick, I'll close everything and go slow then report back :)
14:19stompyjTimMc: so far the upside has been well worth the downside for us. and eventually, I"m sure we'll be able to use docker to spin up a single vm instance, and use docker slices to add services on top
14:19dnolenseancribbs: pong
14:23jcromartieis it bad practice to use assertions for business logic checks?
14:24mdrogalisjcromartie: It depends :P
14:24mdrogalisI think it depends mostly on how you want to react to failure.
14:24randomendusercemerick, my fault! (cemerick.piggieback/cljs-repl :repl-env (cemerick.austin/exec-env)) was exactly what I was looking for. Very slick
14:25cemerickrandomenduser: (cemerick.austin.repls/exec) is even shorter if you really just want a REPL w/o any ceremony :-)
14:25randomendusercheers :)
14:25jcromartiecomparing (assert x "Invalid x") to (when-not x (throw (IllegalArgumentException. "Invalid x")))
14:25jcromartieI certainly prefer to write the former
14:26mdrogalisjcromartie: There's a little more to consider than that. Where do the assertions go? Complected with the business logic? Where does the failure reaction go?
14:27jcromartieunfortunately it's in a messy routine that executes a bunch of outside API calls
14:28mdrogalistbaldridge: Hector sounds sleepy lol
14:29jcromartieit's a command pattern, and performing the command returns events that are then applied to the read model and stored, or else an exception is thrown and the whole thing is abandoned
14:29seancribbsdnolen: wow, my RTT sucks :D
14:29seancribbshahah
14:30jcromartieif I thought I could provide some useful feedback then I'd use ex-info
14:30seancribbsdnolen: i think what I'm struggling right now is app structure/organization, and what 'owner' is in the functions in your todomvc example.
14:30mdrogalisjcromartie: Maybe this might work? https://github.com/MichaelDrogalis/dire#preconditions
14:30dnolenseancribbs: it's the backing React component
14:30seancribbsok, so like the "parent" in the DOM sense?
14:31seancribbsoh wait, i see now
14:31seancribbsn/m
14:31dnolenseancribbs: I wanted to remove the React-isms and make it a bit more Clojure-like, in React you would typically define a new React class per component, with React.createClass
14:31jcromartieinteresting
14:32dnolenseancribbs: in Om we have a single component which allows to present a much more functional and immutable value oriented API
14:33TimMcstompyj: Good to hear, because I'm currently running like 10 other services on my laptop and not thrilled about it. :-P
14:33dnolena single React component I mean, called Pure
14:34Jardadnolen: how does http://holmsand.github.io/cloact/ compare to OM?
14:34dnolenJarda: it doesn't enforce a component design which makes app-state snapshottable
14:34stompyjTimMc: yeah, for us, half our team is osx, and the other half is linux, and we had issues with people struggling to install dependencies, etc
14:34stompyjand the vagrant environment cleaned all that up
14:35TimMcJarda: "cloact" sounds like a part of bird anatomy :-(
14:35dnolenJarda: Om does, and I have some things planned around that
14:35JardaTimMc: also cloact seems to be a drug of some kind (according to google results)
14:35Jardadnolen: ok
14:36TimMcJarda: Probably something for constipated chickens.
14:37hyPiRionI think calling it "Cloak'd" would've fixed some naming issues
14:37Jardait's not my project
14:37Jardasomething I catched up on the internets
14:37TimMcstompyj: My dream: Press a button to spin up all the dependencies of a service, configured to point to each other, built from the branches I specify.
14:38TimMcYes, it would be server-expensive and possibly slow, but imagine how much less frustrating it could be.
14:38stompyjTimMc: yeah, so if you have a box that can handle multiple vms, then vagrant can do that for you today (this is how we're doing things)
14:39stompyjTimMc: Once docker integration happens, then you should be able to do all that from one vm, so it would be even more lightweight
14:39TimMcstompyj: This would require projects to know/report their dependencies in a way that a VM manager could use.
14:40nooniani tried something like that using pallet but i didn't finish it
14:41hiredmanpallet is such a yak shave
14:42mercwithamouthwhat's the best way to start up a compojure app from lighttables instarepl?
14:42mercwithamouthin emacs i can just jump right into the project.repl namespace and start server...not so with light table.
14:42mikerodAre there any certain things to look out for that would hurt compilation performance in Clojure on JVM?
14:43tbaldridgemikerod: don't query a server on the moon from inside a macro?
14:43mikerodSuch as, does compilation slow down when there are a lot of reflection warnings/lack of type hints vs many type hints
14:43hyPiRionI would avoid doing (while true) outside defns and defmacros
14:43mikerodtbaldridge: well, that is certainly one good piece of advice :P
14:43stompyjTimMc: did you mean with docker? or just with vagrant? with pure vagrant we just use chef to configure each box as needed. it's the same chef scripts we use to build production boxes on ec2
14:43seancribbsdnolen: but i can still create components that have their own state, right? like, for instance i need a dropdown in this one place that will have some local/transient state
14:44mikerodok, so slow macros
14:44mikerodand infinite looping top-level forms
14:44dnolenseancribbs: yes, om/get-state om/set-state! take the owner and allow this.
14:44tbaldridgemikerod: seriously though, I've only seen slower compilation when doing really heavy code transformations. The core compiler is super fast
14:45seancribbsok, maybe I'm more confused now than before, hah. i just need to poke at it
14:45mikerodtbaldridge: I see. The reason I ask, is currently we have an jar artifact being distributed over a MapReduce cluster that is not compiled.
14:45dnolenseancribbs: the Om separates app-state (kind of like your DB/model in traditional design) from component local state (transient stuff)
14:45hiredmanour big app at work takes a minute or two to load and compile
14:45mikerodso this will be compiled dynamically on each of the nodes. we are probably goign to move to AOT compiling it
14:46seancribbsso om/set-state! changes the props on the local component
14:46seancribbs?
14:46mikerodI've experienced a few minute build times by changing a project to AOT-compiled
14:46dnolenseancribbs: no the component local state
14:46mikerodfew minute build-time increases
14:46dnolenseancribbs: props come from the app state, only way to change that is via transact!
14:47seancribbsso, if i want to say "show this dropdown", i have to put something in the app state
14:47TimMcstompyj: Yeah, first we'll have to get a uniform build system for all these services.
14:47seancribbsthat seems like mixing concerns
14:47TimMcbuild/deployment
14:47dnolenseancribbs: no, you can do that with component local state
14:47dnolenseancribbs: they are intentional separated for this reason
14:47seancribbsok, then we're on the same page
14:47seancribbsi think
14:48stompyjYeah, that's definitely the trick. Getting buy in can be hard, because it's hard to quantity this stuff. But once you get it working, you wonder what the hell you were thinking beforehand
14:48dnolenseancribbs: we actually don't venture too far from the high level React model
14:48stompyjJust like working with mutable data structures :)
14:48dnolenseancribbs: components get their basic data (props) from app state, just like reading that stuff of out of a DB
14:48dnolenseancribbs: if you a component needs to change something in the app state (DB) you need to transact!
14:49seancribbssure, like the items i want to put in that dropdown will be app state
14:49dnolenseancribbs: for transient stuff, local component state is enough, om/set-state!
14:49dnolenseancribbs: exactly
14:49seancribbscool, now i think i have the separation
14:50seancribbsi like the idea of the UI being a set of functions over the app state
14:50seancribbsso much easier to reason about
14:50seancribbsjust hard to break myself out of the MVC junk
14:50bbloomibdknox: you there?
14:51dnolenseancribbs: yes I much prefer this. Not yet set on the names for the functions so I haven't committed to documenting what's there yet in a more visible fashion.
14:51dnolenseancribbs: also as people use it getting a clearer picture of what's needed
14:51seancribbscool. hopefully this experiment of mine can result in some feedback
14:51TimMcdnolen: So this is like data state vs. ui state?
14:52dnolenTimMc: precisely
14:52TimMcSweet!
14:52TimMcI have to take a look at this, that problem has been bothering me for a while.
14:52dnolenTimMc: and the separation is even more important in Om because we render on request animation frame. So in transact! you need to be careful.
14:52dnolenTimMc: you need to check your assumptions
14:53TimMcboy do I ever
14:53dnolenTimMc: but even om/set-state! is better than what you normally get
14:53dnolenTimMc: every component can see it's current local state and what it will become
14:53dnolenmutation that doesn't suck
14:54dnolensame as React here
14:54TimMclike the Kwisatz Haderach
14:54seancribbslol
14:56seancribbsthe nice thing about the app I'm doing is that all data that is loaded from the server is immutable anyway. you can only add new things
14:57seancribbsby "you" i mean some external process
14:57dnolenseancribbs: fwiw, the main advantage in the Om model over React is faster defaults and simple model for access to app state history - if you don't really need/want this then plain React works great.
14:58seancribbsdnolen: well, redraws are a real problem in this app, mostly because of medium-sized (read thousands) of data items
14:58dnolenseancribbs: like 10,000? is this in a giant list?
14:59seancribbsit's somewhat tree-like
14:59seancribbsthe main drag is taking ~1000 items, slicing it into a N-level index and then displaying that as a table
15:00dnolenseancribbs: tree-like will be better, React does not yet provide the hooks required for truly fast rendering of very large lists
15:00dnolenand thus nor do we
15:00dnolen"truly fast re-rendering"
15:00seancribbsyeah, well i need to compute the matrix, heh
15:00seancribbsbut Ember drags with that many bindings
15:00seancribbswhere it's really not necessary
15:02dnolenseancribbs: so does the server give the client a delta or something?
15:02seancribbseventually we'll probably hook up EventSource
15:02seancribbsbut that is turned off for right now
15:02seancribbsso yeah, potentially new information can be added
15:03dnolenseancribbs: then what exactly are you re-rendering? Are you just sending down all the new data?
15:03seancribbsdifferent subsets of the data
15:03dnolenseancribbs: and you just mutate the part of the data that changed?
15:03seancribbserr, sub-"trees"
15:04seancribbsbetter if i just show you, hah
15:04seancribbshttp://giddyup.basho.com (click riak_ee, then one of the dropdowns under 2.0.0)
15:06dnolenseancribbs: wow ouch, locked up my browser had to restart
15:07seancribbsyep
15:07seancribbsETOOMANYBINDINGS
15:07seancribbsSafari is quite snappy on it actually
15:08dnolenseancribbs: yeah Safari seems significantly faster when it comes to DOM ops than Chrome it seems.
15:09seancribbsso my guess is, tell me if i'm off base here... Ember is delaying those DOM updates to the end of the run loop, but not doing them in one batch
15:09seancribbsand it's a complicated tree of templates there
15:12dnolenseancribbs: hrm I really can't say, I don't know Ember, but the UI doesn't seem very complicated to me and that seems crazy slow.
15:12seancribbsyeah
15:12seancribbseasy vs. simple
15:12seancribbsEmber was easy, but is complex
15:13seancribbsand honestly its latest incarnation is grating me, as much as I like Tom and Yehuda it's just too hard to debug
15:14dnolenseancribbs: I suspect you could solve most of your issues w/ just React, nothing here much warrants Om unless you really want to use ClojureScript :)
15:15seancribbscool, I might just start with that, but perhaps come back for the core.async
15:15seancribbs:D
15:24bitemyappseancribbs: Ember wasn't even easy anyway.
15:25bitemyappunless you'd spent a fair amount of time immersed in it.
15:25seancribbsbitemyapp: fair. "easy" if you're used to railsy things
15:27seancribbsnever said "easy" was good
15:27seancribbs:-p
15:27bitemyappseancribbs: I mostly went CL -> Python -> Clojure -> hs, not much interest in Rails/Ruby except when I was forced to dive into it periodically.
15:28seancribbsyeah it was more like, we knew some Ember already when we did this app, it was quick to get going
15:28seancribbswe were on a deadline
15:28seancribbsnow it's just tech debt
15:28seancribbsand it's not our core thing, just a tool we use
15:28seancribbsso it doesn't get updated that often
15:34bitemyappalways regrettable.
15:34bitemyappseancribbs: the only times I've been happy with that sort of stuff in recent memory has been when I was using cljs or fay with the vanilla DOM API, or Angular.
15:35seancribbsbitemyapp: *shrug*. going to try plain react.js and see if i can't speed this sucker up
15:36bitemyappseancribbs: sure, I haven't tried React myself yet.
15:40arrdem$mail ambrosebs thinking about giving a c.c.t talk at c/w?
15:40lazybotMessage saved.
15:41bitemyapparrdem: that would incentivize me to go to c/w.
15:41arrdembitemyapp: if I can prove that either ambrose or bronsa will be at c/w I can get the department to pay for flying me out :P
15:42arrdembitemyapp: so I'm not entirely unbiased.
15:43bitemyappMakes sense.
15:48bitemyapparrdem: having looked at LightTable's code, beyond the fact that c.c.t isn't really JS ready, I can see why it isn't likely to be used.
15:48bitemyappa lot of the editor is uni-typed objects stored globally with some metadata tags and the like.
15:49bitemyappprimary irritation is non-hackability at runtime.
15:51saint_cypherI have a friend question https://gist.github.com/rjspotter/8362283
16:05nooniansaint_cypher: for one thing, ::users/user should just be :users/user
16:06bitemyapp,::user
16:06clojurebot:sandbox/user
16:06noonianusing two colons with a keyword expands out to the namespace qualified one, so ::user (in the users ns) would expand to :users/user
16:06bitemyapp,:user
16:06clojurebot:user
16:07noonian,::sandbox/user
16:07clojurebot:sandbox/user
16:07noonian,::users/user
16:07clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: ::users/user>
16:10kristofHere's a heretical question.
16:10kristofIs the STM system an actor?
16:10kristofOr rather, would it be useful to think of it as one?
16:11tbaldridgekristof: no, it's more like a managed lock system
16:12kristoftbaldridge: Oh, you're the core.async guy. I've watched all the videos I can (that you've released), and I think it's all great stuff :)
16:12tbaldridgekristof: thanks!
16:12kristofGoroutines in general seem like magic, ha
16:12stuartsierra[org.clojure/data.json "0.2.4"] and [org.clojure/java.classpath "0.2.2"] are in the Maven Central repo now.
16:13kristofI'm just mostly impressed with the way the go macro deep walks a bunch of code and sets up a state machine accordingly
16:13kristoftbaldridge: Question, is there only one STM per running clojure process?
16:13stompyjbitemyapp: you're saying you think light table isn't likely to be used? (sorry, only read half the convo)
16:15tbaldridgekristof: not really. The way STM works is a lot like locks are used in any Java program. But in STM threads can "barge" locks. So one thread locks the refs it needs, does its work, and then only commits if someone else hasn't barged the locks. If there's a barge then the thread drops all its work and retries.
16:17saint_cyphernoonian: thanks.
16:18nooniansaint_cypher: np, other than that i'm not shure whats going on, you might need to make sure you are calling authenticate in your middleware
16:18kristoftbaldridge: Oh, I think I understand now. So you can concurrently access two refs and commit to both of those at the same time if they're not the same ref, right?
16:18tbaldridgekristof: *if they're not in the same transaction
16:20kristofOk, that makes sense.
16:20tbaldridgekristof: but yes, that's the general idea. Although I was surprised to find how little I need STM. Actually I can't think of a single time I've used it and didn't refactor it out later
16:20tbaldridgekristof: it's often much easier to put a hashmap in a single atom, or something like that.
16:20mrhankyi need some hints, i have a clojure script which calls (read-line) to read user input (the script realises a repl). i know want to port this to clojurescriot, so i defined a read-line myself. i use a javascript terminal (jq-console) to handle input/output. my (read-line) starts a new input prompt of jq-console, but my read-line returns a nil immediately and the script failes. how can i "block" the execution of my ported script until a
16:20mrhanky input is made?
16:20kristoftbaldridge: Under what circumstances do you find that you really need to coordinate and synchronize state changes?
16:21kristofI mean, I suppose you just answered that, but can you think of anything?
16:23tbaldridgethat's the problem, I don't really use it much at all. And have rarely (never?) seen it in production code. Normally things are either async, and so core.async or agents are used. Or people just an atom with a hashmap. I think you might want refs if you have a number of refs, and enough threads that they are tripping over themselves during swap!
16:23technomancyI feel like refs would be a lot more useful outside the server-side context
16:23tbaldridgeAlthough even then I'd be tempted to throw all the updates into a core.async channel and serialize them. So yeah, I wonder sometimes if refs aren't superseded by core.async.
16:24technomancybecause you're more likely to be able to fit everything in one process
16:24arohnertbaldridge: I find refs are superseded by my DB more than core.async
16:24arohnerI almost never want to transact on something that I don't want written to disk
16:25amalloymrhanky: javascript is single-threaded, so a blocking approach won't work. you have to switch to a callback mechanism, either by hand or using core.async
16:25tbaldridgearohner: yeah, that too. Esp if you use Datomic.
16:25arohneryup
16:25mrhankyamackera, yeah, i just came accross core.async
16:25mrhanky* amalloy
16:25kristofarohner: the point of datomic was to really run in memory and only commit to disk occasionally, wasn't it?
16:25stcredzeroWhat would be the best way to do server push from clojure to a clojurescript client? (Could also be js client)
16:25arohnerkristof: I don't think I'm qualified to comment on that, given other people in the channel, but IMO no
16:25tbaldridgekristof: no in server mode all data is always written to disk.
16:26kristofok.
16:26tbaldridgekristof: there is a memory only mode for Datomic however.
16:26hansel-hanis there any reason to use a default location like /var/www/example.com/public_html instead of just ~/public_html?
16:26kristoftbaldridge: Hand-wavey question. Is Cognitect an exciting place to be at? :)
16:27ToBeReplacedstcredzero: you have a ton of options... i would decide which web technology you want first (SSE, websockets, other)
16:28tbaldridgekristof: no. it's horrible. They make us work on open source projects sometimes, and I have to program in Clojure all day.
16:28arohner:-)
16:28stcredzeroToBeReplaced: I'm writing a game with as thin a client as possible, but still needs to be responsive. It's a roguelike, so all it does is pass keypresses to the server and displays a 80x24 ascii grid.
16:28tbaldridgekristof: ofcourse! I love it.
16:29kristof:)
16:29wink> Chinese spy manages to steal last 50MB of Lisp program governing U.S. missile launches. Fortunately, it was all closing parentheses.
16:29winkbest lisp joke I heard in months :D
16:29stcredzeroToBeReplaced: I also would de-prioritize browser compatibility.
16:30ToBeReplacedtbaldridge: core.async eliminated the clojure concurrency primitives altogether for us -- we store application states in "system" variables with control channels and go loops -- feels great
16:30bitemyapptbaldridge: I'm with arohner on refs/core.async/dbs
16:31bitemyapptbaldridge: refs are superseded by Datomic :)
16:31lockshas anyone implemented a card game? I only got to https://github.com/locks/sueca/blob/master/src/sueca/core.clj before getting coder’s block. my brain has a hard time thinking clojure still
16:31bitemyapparohner: how have you been?
16:31arohnergood. busy
16:31bbloomlocks: stuartsierra has a good talk about a poker game in clj
16:31arohnerstill not on datomic yet
16:31arohner:-P
16:31bbloomlocks: well, it's more about working with data, but he uses a poker example
16:31ToBeReplacedstcredzero: since you have back and forth, i would consider something like https://github.com/lynaghk/jetty7-websockets-async
16:32tbaldridgeToBeReplaced: bud don't you loose instant deref with that?
16:32arohnerit's amazing how many things there are to do, that aren't the things you want to work on
16:32bbloomlocks: http://www.infoq.com/presentations/Thinking-in-Data
16:32bitemyapparohner: I didn't figure you were. I've assumed that when you were ready to test a migration, you'd do something with berossus first.
16:32bitemyapparohner: sorry, brambling.
16:32tbaldridge*but
16:32bitemyappI keep naming all my projects with the letter b and it's causing me to scramble them a bit.
16:32ToBeReplacedtbaldridge: explain?
16:32arohnerbitemyapp: is the story on datomic migrations any better yet?
16:32locksbbloom: yeah, I even tweeted at him thanking, but it’s pretty thin on the main “run loop” and code
16:33bitemyapparohner: I'm still the only show in town.
16:33arohnermight be a good post to the newsgroup
16:33locksbbloom: I did learn some useful things from his talk
16:33bitemyapparohner: and I'm still open to incremental/differential migrations.
16:33bitemyapparohner: but, my workplace hasn't needed it yet, so I haven't implemented it yet because my at-home projects are Haskell right now.
16:33tbaldridgeToBeReplaced: you said you're storing app state as locals inside gos. How does one go get access to the data inside another go?
16:33arrdembitemyapp: I think that the lack of cljx support is important, but I think that there are major usability concerns that need to come first.
16:33arohnerbitemyapp: Circle has never had planned downtime, so I don't plan on starting now :-)
16:34bbloomlocks: just takes some practice. start by trying to figure out what operations you need & what the data structures need to look like to support those operations
16:34bitemyapparohner: part of the reason I am holding off on incremental migrations is that I want a second pair of eyes on Brambling.
16:34ToBeReplacedtbaldridge: control channels -- the go loops alt and look for requests of "where am i at?"
16:34arrdembitemyapp: and yes. writing programs in top type isn't condusive to using a more restrictive system.
16:34ToBeReplacedtbaldridge: might be a bit clunky... first forays into CSP
16:35bitemyapparrdem: but it was a clever way to defeat static analysis.
16:35bitemyapparrdem: if that was ibdknox's intent :)
16:35locksbbloom: I’ll keep at it, thanks
16:35arrdembitemyapp: :/ on an open project? doubtful, but possible.
16:35bitemyapparohner: I don't want to implement incremental migrations myself and then tell startups/businesses, "ya sure, trust this with your data" unless at least one other reasonably competent person has given it a look over.
16:35bitemyapparohner: I was being facetious.
16:35bitemyapperrr
16:35bitemyapparrdem: I was being facetious.
16:36bitemyapparohner: if the ROI on switching to Datomic isn't worth poking at a migration tool then it's probably not yet time to make the switch anyway.
16:37stcredzeroToBeReplaced: Thanks! That looks just beautiful!
16:37arohnerbitemyapp: it's time, but I haven't heard a strategy, even in theory, to get schema migrations yet
16:37arohneralso, it's been time for a while, but we can never find the bandwidth
16:38bitemyapparohner: there already is a way to do arbitrary schema migrations with Brambling, do you mean in-place
16:39bitemyappadd a ? to the end of that.
16:39arohnerin-place isn't a strict requirement, but zero downtime and no races is
16:39arohnerso migrate into a second DB, but then you need to handle the switchover
16:39bitemyappI'm not sure where a data race with Brambling would happen.
16:40bitemyapparohner: the only Datomic support schema changes that are likely to be supported in the near future are the adding (removal?) of indexes and possibly uni-directional cardinality promotion.
16:40arohner(I don't mean brambling needs to handle this, I mean I need to understand how my code would work)
16:40bitemyappzero downtime depends on how abstracted your applications are from Datomic.
16:40arohnerbitemyapp: at time t1, all peers are on database d1. you migrate to d2. Then you need to switch all peers over to d2, and make sure all in-flight writes appear on d2
16:40bitemyappit goes back to whether or not you can down a clean hand-off with a query queue.
16:41bitemyappthat's how you avoid races and downtime, at least as a first pass.
16:41bitemyappcan do*
16:41arohneralso, duplicating the data size just to do a migration :-(
16:42bitemyapparohner: if your applications are calling your database directly, that's not good. You need a middleware layer / queue like larger services.
16:42bitemyappthe middleware layer / queue makes the hand-off safe and prevents any lost transactions.
16:42arohnerit still sounds like there's a race there
16:42ToBeReplacedtbaldridge: i'd also appreciate critique if there's something clearly funky with that approach -- it's true that we don't get instant deref b/c you have to wait for the go block to alt again. It might make more sense to just have each block update an atom to deref against. however, we need (or think we need) the control channels anyway so it didn't seem awful
16:42bitemyapparohner: I don't think so, the queue/middleware layer is pausing for the length of the final migration.
16:43bitemyapparohner: but the reason for incremental migrations is to make that final migration VERY short
16:43bitemyapplike, not detectable by your users.
16:43bitemyappI thought I'd explained all this before.
16:43arohnersorry, it's been a while
16:43arohnerwhere the final migration is incremental, over the time since the 'full' migration finished?
16:43bitemyappthe only real source of delay would be long running transactions/queries.
16:44bitemyapparohner: it's zeno's paradox type thing.
16:44tbaldridgeToBeReplaced: yeah, it depends on the app. But as a whole that's one of the issues with actor systems. The actor can get backed up, and then it can't be deref'd. But YMMV.
16:44bitemyapparohner: you're incrementally catching up the destination to the origin over and over until the differential is so small that a final migration should take no time at all.
16:44arohnerright
16:44bitemyapparohner: then for that final migration, you bring the hammer down in your middleware/queue to hold the boat, let things wrap up, then flip over.
16:45bitemyappmy only real complaint is the data duplication, but I don't think it's expensive at your scale, especially if you're using EC2.
16:46ToBeReplacedtbaldridge: was your comment earlier that you're finding that you're not shipping refs anymore, only atoms (and agents?)
16:46arohnertbaldridge: any hope on this stuff (zero downtime schema migrations w/ datomic) getting easier? :-)
16:46bitemyappfrom there you can do a differential archive of the contents of the origin/old database against some archival instance and then kill 'em off.
16:46arohnerbitemyapp: I worry more about the pain-in-the-ass factor than the cost
16:46arohner(though cost does matter some)
16:46bitemyapparohner: I've been bugging Cognitect about it, what I mentioned earlier is the only thing they've explicitly said they'd be comfortable doing.
16:47bitemyapparohner: I don't worry about the cost arising from the data duplication, just the operational ick.
16:47tbaldridgearohner: I'd ask bobby or stuart in #datomic. They are more qualified (and authorized) to speak to that.
16:48arohnertbaldridge: thanks. Which stuart? :-)
16:48bitemyapparohner: probably the dude with the rock star hair.
16:48tbaldridgearohner: stuart h works full time on Datomic. Bobby specializes in customer relations for datomic.
16:49bitemyappBobby's almost always the one answering my questions.
16:49bitemyappHalloway's accidentally responded once I think.
16:49bitemyapptbaldridge: neither seem to be in the channel though.
16:50bitemyappand I'm loathe to file a ticket for something I'd already asked them about in the past.
16:57logic_progwhy are nested #( ... % ... ) 's not allowed?
16:57logic_progwhy not have % bound to the nearest # ?
16:57tbaldridgelogic_prog: that would be super easy to get wrong
16:58tbaldridgeand #(%) is just gross anyways (imo)
16:58ucbbitemyapp: !
16:59amalloy(map #(map #(map #(+ % %) %) %) xs) doesn't read super-well
16:59TimMctbaldridge: Nonsense, where would swearjure even be without it?
17:00bitemyappucb: I sent you a lot of music.
17:00ucbbitemyapp: I saw my name highlighted but lost the backlog :'(
17:00bitemyappmuh lord.
17:01bitemyappucb: http://kasperrosa.bandcamp.com/track/coronal-mass-ejection http://dumbsaint.bandcamp.com/album/something-that-you-feel-will-find-its-own-form
17:01ucbmuh limechat.
17:01bitemyappthis is why I am civilized and use a persistent IRC session.
17:02ucbthanks!
17:02bitemyappucb: and https://soundcloud.com/you-are-not-cat/tangled-up-in-clouds https://www.youtube.com/watch?v=YQ1wsf7tAE0
17:02ucbme too, but limechat is a piece of gunk
17:02bitemyappucb: last one comes by way of akurilin. post-punk'ish hardcorey stuff. good.
17:02ucbcool!
17:03TimMcbitemyapp: Do you have somethign set up that collects all your highlights in another file?
17:03TimMcIf I forget to /away, it's really annoying to figure out where a highlight came from when I get back.
17:03rasmustohilite for irssi is kewl
17:03bitemyappTimMc: I just have logs.
17:03bitemyappTimMc: and /lastlog
17:03TimMcFair.
17:04bitemyappTimMc: arrdem's setup is even better, he gets a phone jingle.
17:04TimMcI highlight on more than just my nick, though.
17:04bitemyappTimMc: be sure to use this knowledge for evil liek I do.
17:04bitemyapplike*
17:04bitemyappI don't highlight on anything but my name. Nobody talks about my libraries.
17:04bitemyappexcept occasionally on the mailing lists.
17:04bitemyapps/occasionally/rarely/g
17:05bitemyappucb: https://www.youtube.com/watch?v=hzMeU8tuvNE
17:05mikerodWhy is the type hierarchy of Clojure functions so... big?
17:06bitemyappmikerod: I mean, it's not Spring Framework.
17:06mikerodAFunction, AFn, IFn, Fn
17:06mikerodwat
17:06bitemyappmikerod: have you ever tried to make something nice in Java?
17:07mikerodbitemyapp: haha, ok I guess that is a fair enough explanation
17:07bitemyappmikerod: Clojure's implementation is pretty solid at the ground floor, IMHO.
17:08lockswhat about clojure on CLR :P
17:08bbloommikerod: IFn is for things that can be called like functions. AFn is used internally to deal with some ugly java crap about variadics via implementation inheritence, Fn is a marker interface for saying "this is a real function", and AFunction is the implementation of Fn
17:08bitemyappmikerod: you don't want to roll all this stuff into a single class.
17:10rasmustoeverything is a class, a class is everything
17:10mikerodbbloom: that is a good explanation of these things that I certainly haven't heard befor
17:11mikerodbefore*
17:11bbloommikerod: all you really need to know as a user is that there is clojure.core/ifn? and clojure.core/fn?
17:11mikerodbitemyapp: I know that smaller, composable interfaces (abstractions) are favorable to monolithic ones; especially in the Clojure core
17:11bbloommikerod: implementation wise, you've also overlooked RestFn and a few other things
17:12bbloomthat's the point of AFn and Fn. AFn lets all the concrete impls share stuff and Fn lets you do fast testing against an interface for clojure.core/fn?
17:12bbloombut maps and vectors and things are not functions, they can only be called LIKE functions, hence ifn?
17:15bitemyappucb: https://www.youtube.com/watch?v=efsUakRY2IQ
17:16ucbbitemyapp: http://www.youtube.com/watch?v=_G3UsM0D6aA
17:16bitemyappbbloom: do you listen to music while coding?
17:17RaynesWho doesn't?
17:18ucb+1
17:18Raynesbbloom jams out to Grimes while he codes.
17:18RaynesNot the band, podcasts featuring me.
17:18bitemyappucb: surf doom?
17:18bitemyappRaynes: that chick is spooky yo/
17:18ucbbitemyapp: never heard of it
17:18eggheadlol
17:18eggheadgrimes while devvin
17:18bitemyappucb: that's how I'm describing what you sent me.
17:18eggheadI've been listening to lee bannons new album while devvin
17:18ucbbitemyapp: oh! heh. Never had somebody refer to The Coral as surf doom :)
17:19bitemyappucb: s'what it sounds like.
17:19bitemyappI should write a thesis on genre bucketing.
17:19RaynesI listen to recordings of bitemyapp played at 0.5x speed
17:19eggheadis anthony grimes a member of the band grimes???
17:19lazybotegghead: Yes, 100% for sure.
17:19eggheadty lazybot
17:19Raynesegghead: I wish :(
17:19bitemyappthat would be hella cool if it was true.
17:19RaynesScrew programming, music is my passion.
17:19RaynesThat's not true, but I am a wannabe singer. <3
17:20eggheadwe can start a band Raynes
17:20eggheadwe'll use overtone and livecode
17:20RaynesI'm down.
17:20bitemyappI need to learn to play keyboard.
17:21eggheadoh nice do you play keyboard? nah I play emacs
17:21eggheadi'm sure we could get a gig at the echoplex those guys let anyone
17:23mikerodLooks like I lost my connection, thanks for the IFn and Fn family explanations
17:23mikerodI feel a little more at ease on it now
17:26stuartsierramikerod: I made a little utility to help visualize those class hierarchies https://github.com/stuartsierra/class-diagram
17:26stuartsierraAnd somewhere on the web is a giant diagram of all the Clojure classes/interfaces.
17:27mikerodstuartsierra: Oh, I forgot I came across this I think a while back. This is definitely useful.
17:27dnolenhttps://raw2.github.com/Chouser/clojure-classes/master/graph-w-legend.png
17:28stuartsierrathat's it
17:28mikerodawesome to both
17:33lockswait, Clojure has classes?
17:33locksI’ve been lied to
17:33locks:P
17:37hyPiRion:gen-class man
17:37logic_progin core.async, is there a way to say : create a new channel by (1) taking everything from chan1, then (2) take everything from chan2?
17:37logic_progbasically, I want a way to concat two chans
17:46AeroNotixis there anything like `doto' which returns the value of the last form?
17:47bbloomAeroNotix: not precisely, but there is .. which is for chaining style, like if you have a "fluent" builder or something from java land
17:47bbloom(doc ..)
17:47clojurebot"([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."
17:48AeroNotixbbloom: that's different
17:48bbloomAeroNotix: i'm aware. hence i said "not precisely"
17:48AeroNotixoke doke
17:49bbloomwas just guessing, since that's a popular thing in java libs for functions that always return "this"
17:49AeroNotixI can write a macro for this (most likely just copying the majority of doto)
17:49AeroNotixany reasoning why doto returns the original value?
17:49AeroNotix(doc doto)
17:49clojurebot"([x & forms]); Evaluates x then calls all of the methods and functions with the value of x supplied at the front of the given arguments. The forms are evaluated in order. Returns x. (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"
17:49AeroNotixreturns x
17:49AeroNotixL
17:50bbloomAeroNotix: it returns the original b/c you're presumably mutating it and then want it
17:50bbloomAeroNotix: i wouldn't copy doto, i'd delegate to it
17:50AeroNotixhmm, indeed. Could be a reason
17:50justin_smithif you want the last result, you can use -> or ->> instead of doto, which assume functinoal rather than mutational chaining
17:50AeroNotixjustin_smith: but it doesn't work if the functions are mutating a java object, instead of returning values
17:50noonianjust make sure your calls return compatible values
17:51AeroNotixIt's not my Java code
17:51nhjknoob question, but is it worth it to learn some java because clojure is based on the jvm?
17:51AeroNotixnhjk: somewhat, I've found
17:51stuartsierralogic_prog: maybe something like this (totally untested) https://gist.github.com/stuartsierra/8364220
17:51AeroNotixyou'll be exposed to it. Namely things like how java organizes code
17:51AeroNotixand a lot of useful stuff is in the java stdlib
17:51technomancynhjk: you need to learn to read it eventually, but learning to write it is a waste of time
17:52justin_smithlearning java is meh I think, but knowing enough so you can read javadoc and do interop? definitely
17:52AeroNotixexactly
17:52logic_progstaurtsierra: noted, thanks!
17:52AeroNotixJust enough so you can read function signatures would be nice.
17:52stuartsierralogic_prog: just fixed to return `out`
17:53AeroNotixhaha, I love going away from Clojure to Go, and then coming back to Clojuer
17:53AeroNotixClojure*
17:53justin_smiththe three java skills needed in clojure: jvm config / tuning / classpath; reading javadoc; reading stack traces
17:53AeroNotixClojure stack traces are fugly, jus' sayin'
17:54justin_smiththey are, but knowing how to read them is a must, for now
17:54rasmustoIFugly
17:54stuartsierraWhenever I hear that, I think "Compared to what?"
17:54noonianlol
17:54AeroNotixstuartsierra: some languages which don't include internal machinary
17:54AeroNotixin their stack traces
17:54nhjkalright thanks, I'm already familiar with the syntax because of an algorithms class, but I'll dive a little deeper!
17:54stuartsierraWhat language does that?
17:54AeroNotixThere's references to things like `apply' interspersed with all my stuff.
17:54nDuffAeroNotix: ...and you can use available tools and libraries in Clojure to strip them out here.
17:54technomancycompared to nearly everything
17:54nDuffAeroNotix: ...if you're so inclined.
17:54AeroNotixnDuff: such as?
17:55AeroNotixI use emacs, probably cannot switch at this point.
17:55nDuffAeroNotix: clj-stracktrace, f'rinstance
17:55technomancyracket actually has different stack trace styles for its beginner languages vs its expert ones, which is brilliant
17:55AeroNotixstack traces to 11
17:55mikerodI don't really care if the stacktrace shows the Clojure internal functions being called. I don't see what is hard about finding the relevant code that causes the issue in that.
17:55mikerodThe harder things are when it is a compiler-time error
17:55technomancynDuff: clj-stacktrace doesn't actually remove any gunk
17:55hiredmanwhat a pain it must be to debug things when the runtime is actively trying to hide things from you
17:55nDuffAhh. I've seen stuff that did, but not paid much attention.
17:56AeroNotixnDuff: clj-stacktrace still includes crap in the trace
17:56mikerodThe worst is when it is no-source-file eval-fns
17:56nDuffAeroNotix: As I said above, I've not paid much attention to those tools.
17:56stuartsierra^ What hiredman said.
17:56AeroNotixclojure.lang.RestFn.invoke, like what the hell does that need to be in the stack trace for
17:56technomancyhiredman: actively hiding stuff from you is what abstraction is all about
17:56mikerod^ to not hiding details of the stack
17:56stuartsierraI dunno, maybe because it was on the stack?
17:57nDuffAeroNotix: ...ahh, https://github.com/AvisoNovate/pretty was the more recent one
17:57AeroNotixstuartsierra: sure, but it's not anything that's to do with me, really. If you need that, it should be configurable
17:57AeroNotixstuartsierra: as in, some variable which you can set for stack trace verboseness
17:57dnolenAeroNotix: *sigh* it is configurable today, no one uses it
17:57stuartsierraWhat's next, configurable core dumps? Configurable segfaults?
17:57stuartsierraConfigurable BSOD?
17:58nDuffAeroNotix: ...it's not filtering things, but it is using highlighting to distinguish
17:58locksI’d configure segfaults to —never
17:58AeroNotixnDuff: it's better
17:58AeroNotixdnolen: any docs?
17:58dnolenAeroNotix: you can get pretty stack traces since 1.3
17:58AeroNotix> any docs?
17:58dnolenAeroNotix: it the default behaior of clojure.repl/pst
17:58dnolenAeroNotix: pst has been doc forever
17:59dnolendoc'ed
17:59technomancythat's a pretty low bar for "pretty"
17:59dnolentechnomancy: we've already discussed this like a million times :)
17:59dnolenclj-stacktrace is an abomination
17:59stuartsierra`psh` also conveniently hides the cause chain, breaking any attempt by a library designer to provide a useful error message.
17:59stuartsierra`pst`
17:59dnolenstuartsierra: I'm not condoning it by any means
17:59technomancydnolen: everything is terrible; I agree there
18:00bitemyappthe complaining is partly why I stopped trying to improve clj-stacktrace.
18:00stuartsierraJust this week I had to hunt for an exception that clj-stacktrace swallowed.
18:00bitemyappI went back to banging rocks together.
18:00dnolenbut if people want to find out about stuff they'll eventually abandon, who am I to get in the way :D
18:00technomancy"Everything is great the way it is" just means we've lowered our standards
18:01mikerodwhat is clj-stacktrace, never heard of this one
18:01AeroNotixI guess eventually I'll just tune out the noise
18:01stuartsierraa pretty stacktrace is like a pretty autopsy.
18:01mikerodohhh, yes I have
18:01bitemyappmikerod: you are...so lucky I've sworn off lgtfy.
18:01AeroNotixstuartsierra: that's a terrible opinion :)
18:01kristofEspecially with java stacktraces, hah.
18:01kzardnolen: Going to have a look at om hopefully this weekend, is it ready for production stuff in your opinion?
18:01stuartsierrai.e. if it's pretty you're going to hide lots of important details
18:01bitemyappstuartsierra: I think stacktraces can get cleaned up and bracketed without dropping information.
18:01AeroNotixstuartsierra: it's a post mortem on a sometimes critical part of your system. You need that information to contain what you need exactly.
18:01bitemyappstacktraces wouldn't be so damn critical if we had sensible types.
18:01stuartsierraYes, which is why it shouldn't hide anything.
18:01mikerodbitemyapp: hah I looked it up, stupid question
18:02dnolentechnomancy: I think anyone who has done CLJ long enough likes verbose stack traces, as long as it's not deep in the compiler or the reader
18:02kristofbitemyapp: Oh? Why?
18:02bitemyapplogging/tracing is usually more valuable and semantically relevant than stacktraces.
18:02technomancystuartsierra: so do you turn on GC logging too?
18:02mikerodI was thinking the discussion was of clojure.stacktrace
18:02bitemyappkristof: source/sink distance on errors.
18:02technomancywouldn't want to miss anything important
18:02bitemyappkristof: if the compiler is catching 90% or more of the common-case stuff, then it's less often that you need to pick through a stacktrace.
18:02dnolenkzar: it's pre-alpha, things are going to change
18:03dnolenkzar: it's worth assessing, not building critical stuff on. Though that doesn't appear to be stopping anyone.
18:03hyPiRionThere are some pretty good ideas and concepts in Racket, CLisp and Erlang on how to read stack traces and issues in programs.
18:03technomancydnolen: so anyone who doesn't like it just hasn't been using clojure long enough? interesting.
18:03bitemyappkristof: in the rare occasion when I need to look at a stacktrace in, say, Haskell it's because I had an unintentionally non-total pattern match.
18:03hyPiRionEven gdb/lldb would be good/valuable.
18:03bitemyappkristof: it then tells me what value I failed to match, then I add the match.
18:03dnolentechnomancy: I don't think that's all that weird
18:03bitemyappkristof: source->sink distance: 0
18:03kzarOK good to know, still am intrigued enough to want to spend my weekend looking at it. Curious if it could replace AngularJS
18:03technomancyhow many years does it take?
18:04dnolentechnomancy: I once thought not being able to set locals was stupid
18:04bitemyappkristof: source->sink distance of my average Clojure stacktrace? ohgod.jpg
18:04technomancymaybe two or three more years and the beauty will sink in
18:04technomancyand I'll stop being such a noob
18:04bitemyappkristof: I would be willing to bet OCaml users have a similar experience.
18:04stuartsierraNo one ever said they were beautiful.
18:04dnolentechnomancy: it's not about pretty / not pretty
18:04bitemyappthere are ways to make stacktraces more readable/usable without dropping info.
18:04mrcheeksdnolen: 'completeness' of the stacktrace then?
18:05dnolenmrcheeks: not missing critical information
18:05bitemyappIf everybody agrees on that point then we can just discuss what those improvements could be.
18:06bitemyappI'm pretty sure everybody understands stack-trace elision is a bad idea.
18:06mikerodmrcheeks: we want them the stacktrace to be both complete and sound
18:06dnolenwhat makes me laugh about all of this is that the main reason that CLJ stack traces are so noisy are precisely the same reasons that CLJS stack traces aren't
18:06mikerod:P
18:06dnolendecomplected compile/runtime
18:06stuartsierraI believe .printStackTrace is good enough, and every attempt I have seen to "improve" it ends up having subtle bugs that lose the original exception.
18:07stuartsierras/subtle/edge case/
18:07technomancystuartsierra: the only lib that's even attempted is a 3-year-old abandoned hack
18:07technomancywhose author ran off to write Google go code
18:08justin_smithlocks: I once wrote a c program for win98, no segfaults is not a bonus
18:08technomancyhardly compelling
18:08stuartsierraThere are 2 stack-trace printers in Clojure alone, `pst` and clojure.test.
18:08justin_smiththe alternative to segfault is worse
18:08bitemyappjustin_smith: mmmm data corruption
18:08stuartsierraRegrettably I wrote one of them. I've learned my lesson.
18:08technomancypart of the reason no one tried picking that up is that chouser said he was going to do it
18:08stuartsierraAnd then decided it wasn't worth it.
18:10technomancyclojurebot: usability is not a big deal
18:10clojurebotYou don't have to tell me twice.
18:10Bronsaarrdem: I'm afraid there's no way I'll be at clojure/west, San Francisco is a long way from Italy
18:13supersymfacebook does their whole operation in mysql? ... those nr's kinda blow my mind
18:14bitemyappsupersym: no. It's not that simple.
18:14arrdemBronsa: this doesn't especially surprise me :P
18:14supersymwell they partition the whole thing ofc but still
18:14arrdemBronsa: wish you could make it tho
18:14bitemyappsupersym: the messaging backend persistence layer is HBase (they hired a ton of ex-Yahoo! people). Some of their core persistence layer is MySQL.
18:14supersymyeah
18:14bitemyappsupersym: it's an inaccurate statement, there are many data stores at Facebook.
18:14supersymok... I read that 90% doesn't scratch the db layer
18:15supersymcaching mostly
18:15bitemyappMySQL is their "primary" one in some sense, but sharded MySQL as facebook is a completely different animal than you might be thinking of.
18:15bitemyappsupersym: some of that is TAO, some of that is other things.
18:15supersymtrue in that sense, I must be my wording ;)
18:15bitemyappsupersym: they have an aggressive cache dependency graph built in TAO on top of memcached.
18:15bitemyappif B depends on A, and A gets busted, B must be busted too.
18:16supersymI never heard of TAO... going to read up some on that
18:16bitemyappsupersym: their whole OLAP stack is Hadoop.
18:16bitemyapponly the core OLTP is the sharded MySQL, and realistically, most read requests are served by TAO/memcached if things are going well.
18:16supersymIts that I got involved with this magento shop now (they use this pretty advanced EAV setup) that I got to work with mysql again
18:17supersymbut it really wants to make me stab my eyes out the whole PHP/HTML soup
18:17bitemyappsupersym: you do not want to model your backend stack based on anything Facebook does.
18:17bitemyappSeriously. Don't.
18:18supersymbitemyapp: nah... purely noticed for the fact of it, and what can be done as 'nice to know'
18:18bitemyappmaking your own EAV for an ecommerce site seems terribly unwise.
18:18bitemyappif you really need EAV, there's always Datomic though.
18:18supersymnothing planned on that front, I was actually wondering if I couldn't do better clean slate with clojure and datomic :P
18:18bitemyappclean slates are pretty risky.
18:19bitemyappincremental migrations are better.
18:19bitemyapppick off pieces of your stack and port a single component at a time.
18:19supersymmy idea
18:19supersymyeah
18:19bitemyappsupersym: there are books on how to deal with legacy code-bases. Divide and conquer.
18:20supersymbitemyapp: thanks, I really do feel there is a case here but indeed, I should approach this from certain angle
18:20supersymgot this experienced magento people to bring me up to speed so nice time to pick their brains on some stuff as well
18:22supersymluckily it isn't a huge site in terms of catalog size but still the amount of customization makes every upgrade a huge pain in the ass and those guys are running way way behind in production version already
18:22supersymtakes about 50 hours after 1 or 2 trial runs, according to teh googles
18:22bitemyappsupersym: do you have any questions about Clojure?
18:24supersymwell besides that I wonder in terms of components, my obvious picks would be hiccup, datomic, jetty or probably http-kit but then also styling using garden, compojure ofc, ring, friend probably would be a good one esp. since you've got online payments
18:25bitemyappI use http-kit, Ring/Compojure, datomic, and selmer (instead of hiccup).
18:25supersymall in all a lot of dependencies... chopping it up would seperate those, yet since its still web based, I wonder if pedestal would be a option
18:25bitemyappI avoid hiccup and friend. Garden depends on your frontend people.
18:25supersymits really single page apps I think
18:25AeroNotixWhat're people using for syntax checking in Emacs?
18:26amalloysyntax...checking? what would it check?
18:27supersymbitemyapp: ok I don't think I've used selmer (or have it register for that matter). Any particular reason for picking it over hiccup?
18:27bitemyappRaynes: in Geidi Primes there are moments where she almost sounds like Kate Bush
18:27technomancysupersym: oh man, prepare for a rant
18:27AeroNotixamalloy: it would check if the syntax is valid clojure, what else?
18:27AeroNotixsurely you understand this concept?
18:27supersymtechnomancy: lol
18:27Raynesbitemyapp: I've actually never even listened to Grimes before.
18:27bitemyappRaynes: ZOMG
18:27RaynesI just knew the name because... we share it.
18:28technomancythis used to be like a weekly thing where bitemyapp would complain how terrible web dev in clojure was because he couldn't use hiccup for some reason
18:28amalloyAeroNotix: the only syntax that exists is (stuff), [stuff], {stuff}. write code with paredit, and it's impossible to write incorrect syntax
18:28bitemyapptechnomancy: hiccup is awful.
18:28AeroNotixamalloy: sure. Sure. SURE!
18:28technomancylies
18:28hyPiRionoh, here we go again
18:28AeroNotixamalloy: I'll get RIIIIGGGHt on that
18:28bitemyapphyPiRion: don't fear the reaper.
18:28bitemyappsupersym: just use Selmer. The library speaks for itself.
18:28AeroNotixamalloy: and we both know that there are more invalid pieces of syntax, but whatevs.
18:28AeroNotixe.g.
18:29bitemyapp(invalid lel :lol
18:29supersymlol ok
18:29bitemyappI think the compiler catches that.
18:29technomancysupersym: if you have a team of designers and folks that don't know clojure touching the views, hiccup is not a good fit
18:29bitemyappsupersym: that's not the only reason to use Selmer.
18:29bitemyappsupersym: it also narrows down the origin of template context to a single bottleneck
18:29bitemyappsupersym: makes it super easy to log template context and what caused this or that output
18:29AeroNotix,(let [m {:k :v}] (defn foo [{:keys [k] m}] k))
18:29clojurebot#<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>
18:30hyPiRionAeroNotix: I just attempt to compile the file through cider/nrepl through C-c C-k. If it fails somewhere, there will be error lines explaining what failed
18:30AeroNotixamalloy: very simple error
18:30bitemyappsupersym: you can have m * n "connection points" between templates and your application in Hiccup. It's awful.
18:30supersymtechnomancy: no I guess I should use enlive for that
18:30amalloyyes, i should have written {stuff stuff}, not {stuff}
18:30technomancysupersym: ehrm... you can try that. it can be ... difficult.
18:31bitemyappsupersym: enlive is worse than hiccup.
18:31bitemyappit's also horrifically slow.
18:31technomancy enlive code reads beautifully but when you go to modify it sometimes it can be difficult to know what to do
18:31technomancyit's not slow anymore
18:31amalloyseriously, clojure's syntax is so simple (it really is just lists vectors and maps), and its semantics so flexible (you can define macros that make anything syntactically valid be semantically meaningful), there's nothing for a syntax checker to do
18:31supersymright...well that really makes sense, it's the idea that it would be a more generic concept of e-commerce appliance in clojure but I guess once you venture into Clojure development, you are faced with tons of people who aren't
18:31bitemyapptechnomancy: time to rerun my benchmark suite then.
18:32bitemyappsupersym: so use Selmer.
18:32supersymany freelance work I'd do in clojure and bet my ass people would come back cause it's hard to find developers ><
18:32bitemyappthere are a 1,001 reasons to use Selmer over Hiccup and you just named one of the better ones.
18:32S11001001&(-> (java.text.SimpleDateFormat. "MMM-dd-yyyy") (.format (java.util.Date.)))
18:32lazybot⇒ "Jan-10-2014"
18:32amalloyaside from run the compiler, as hyPiRion suggested, and then let you know if it broke
18:32bitemyappS11001001: non-ISO format? Pagan.
18:33bitemyappamalloy: I said that earlier :(
18:33S11001001bitemyapp: working specifically with UI-side
18:33noonianyeah, the biggest problem with Clojure is that most people hate lisps
18:33bitemyappS11001001: ignore the mewling cries of weak humans and use the standard format.
18:34hyPiRionSomeone sayin enlive is the best thing ever would bring so much joy into this channel.
18:34locksnoonian: lisps are hard to understand (yes, I made that pun)
18:34noonianlol
18:34bitemyapphyPiRion: why?
18:34hyPiRionbitemyapp: That was attempted irony.
18:36bitemyapphyPiRion: Enlive just reinforces my hypothesis that francophones are from outer space.
18:36supersymhaha...I'll give you that ;)
18:38hyPiRionbitemyapp: That's no problem, Clojure is my alien spacecraft anyway.
18:39technomancyhttp://www.lisperati.com/logo.html
18:41bitemyapptechnomancy: almost seems quaint these days.
18:41technomancyit was quaint when it came out iirc
18:46mikerodlisp is only for *real* programmers, obviously
18:47dnolennoonian: considering how many people are in this channel these days, I don't know if any of the old complaints about Lisp really hold up.
18:49nooniani've just found it hard to get other people past it's syntax, i think it being a lisp is a strength for sure but many people don't want to invest the time to become comfortable with it
18:50mikerodnoonian: it's "syntax" is one of the best part, is the irony
18:51noonianyep
18:51mikerodI can't type; is one of the best parts, that's the irony*
18:51bitemyappnoonian: really? I haven't had any trouble teaching it to Python programmers.
18:51mikerodPython people understand first-class functions
18:51TolstoyPeople where I'm at (extremely traditional Java types) become interested as a result of a few of us writing "cool" apps with a simple build system and hardly any code (seemingly).
18:51bitemyappnoonian: on the rare occasion any of them say anything about syntax I give them a withering look that lets them know how shallow they are being and they clam right up.
18:51TolstoyTrying to talk it up never works.
18:53noonianbitemyapp: my withering look must not be as effective as yours :P
18:53bitemyappnoonian: I am feared in three continents.
18:53bitemyappnoonian: the bamboo stick helps.
18:53AeroNotixAt the moment I'm using Clojure because our Erlang application needs to interface with authorize.net and they provide only a SOAP interface. They also provide a Java SDK, so naturally, I'm leveraging that. Using my functional programming experience from Erlang to hopefully help with Clojure.
18:54technomancyAeroNotix: how are you finding that transition?
18:54technomancymy guess would be the language itself would be easy compared to the runtime
18:55bitemyappRaynes: but seriously, listen to Grimes.
18:55hiredmanif only erjang
18:55AeroNotixtechnomancy: fine. I "wrote" clojure a few years ago back when it first came out. I've also written Common Lisp for years
18:55AeroNotixhiredman: no
18:55technomancybut from what I can tell erlang doesn't have a lot of HOF usage going on, so that's pretty different
18:55bitemyapphiredman: pls no
18:55alewbitemyapp: what do you think of crystal castles?
18:55bitemyapptechnomancy: you can't "scale up" Erlang.
18:55AeroNotixbitemyapp: uhhh what?
18:55Raynesbitemyapp: Okay
18:55AeroNotixerlang scales incredibly well, it's kind of the point
18:55bitemyappAeroNotix: I'm talking about FP, not distributed systems.
18:56bitemyappAeroNotix: you can't really grow into high level FP in Erlang.
18:56AeroNotixNot sure what you mean there.
18:56technomancybitemyapp: you mean build out new abstractions?
18:56Raynesbitemyapp: Apparently Gerard Way listens to Grimes :3
18:56bitemyapptechnomancy: it's very difficult, yes.
18:56AeroNotixthere are behaviours
18:56bitemyappalew: not a fan. I think they're hacks. :(
18:56technomancyinteresting word choice, but I see where you're coming from
18:56AeroNotixbehaviours are kind of like Interfaces
18:56bitemyapptechnomancy: Erlang code is generally 0 degrees removed, Clojure 1, Haskell...a lot more.
18:56alewbitemyapp: similar style to grimes imo
18:57AeroNotixand if you couple them with Dialyzer you get semi-static checking
18:57bitemyappalew: I know who they are, I just avoid them.
18:57bitemyapplol. semi-static checking. No.
18:57AeroNotixSo yeah, you can write higher level abstractions like that
18:57AeroNotixbitemyapp: dialyzer is shit, but it helps
18:57bitemyappAeroNotix: dialyzer is a linter on steroids, it doesn't make anything static and truly safe or sound.
18:57AeroNotixit's better than nothing
18:57bitemyappAeroNotix: the point of a type system in FP is to help you scale your abstractions safely, Dialyzer cannot help you with that.
18:58AeroNotixSure, it's no silver bullet. Dialyzer is shit, like I already said.
18:58bitemyappAeroNotix: case in point, if you have a stack of monads Haskell can help you keep your code straight and correct. A comparable pattern in Erlang would be incomprehensible to Dialyzer.
18:58AeroNotix> Dialyzer is shit
18:58AeroNotixI already said this
18:58bitemyappAeroNotix: stop. I'm making a broader point than Dialyzer.
18:58alewso enlive isn't a good choice when working with designers?
18:59bitemyappAeroNotix: that's why you can't really extend yourself beyond simple HOFs in dynamic languages.
18:59alewseems better than selmer would be for that
18:59bitemyappalew: it complects the functionality of your templates with your HTML and CSS. That's insane.
18:59arrdembitemyapp: hiccup?
18:59bitemyappIf you don't have a type system to keep things clear and correct you can't really abstract your FP very much without making it very hard to write correct code.
19:00dnolennoonian: people will ignore syntax if you show them you write better/faster software
19:00AeroNotixYou present a false dichotomy
19:00bitemyappthe point of the types isn't just correctness, it's leverage.
19:00bitemyapparrdem: shush you.
19:00AeroNotixYou can write perfectly correct code in dynamic languages, it's just harder to prove.
19:00arrdembitemyapp: to that, nevar.
19:00dnolennoonian: you can't convince everyone, but for people who don't want to reason, can't do much for them anyway
19:01AeroNotixWhat *is* the comparable thing for Clojure, anyway? (re: dialyzer)
19:01bitemyappAeroNotix: you're not disagreeing with what I just said.
19:01alewselmer builds in the template into the html and css, isn't that coupling them?
19:01AeroNotixbitemyapp: I'm just augmenting it to allow a wider definition
19:01bitemyappAeroNotix: you're misunderstanding what I'm saying because you don't know the approaches I'm referring to.
19:01dnolenAeroNotix: nothing like dializyer, but you've got Typed Clojure
19:01hyPiRionAeroNotix: core.typed I guess
19:01technomancyAeroNotix: there's core.typed, but it doesn't have any of the inference functionality dialyzer has unfortunately
19:01nooniandnolen: right, people have to be willing to try something different
19:01AeroNotixdnolen: how well does that integrate with regular clojure?
19:02bitemyappAeroNotix: the point is that things like map, filter, and reduce are nice, but you can do a lot better and further decomplect your implementations from your interfaces.
19:02dnolenAeroNotix: it designed to integrate with regular clojure
19:02bitemyappcore.typed is pretty ugly and won't really enable the patterns I'm talking about.
19:02AeroNotixdnolen: cool
19:02dnolenAeroNotix: some people already use it in production and seem to like it quite a bit
19:02bitemyappAeroNotix: I think CircleCI uses c.c.t
19:02dnolenAeroNotix: ambrosebs is very reponsive and cranks on it
19:02arrdemAeroNotix: core.typed can be a pain, but it's a nice toolkit.
19:02technomancyAeroNotix: you still have to spec everything top-level, so it's a lot of work
19:02AeroNotixHaskell does provide some very interesting methods of providing really high level abstractions
19:03AeroNotixfunctors, applicative functors are some really light and easy abstractions that make so much sense it's untrue
19:03bitemyappAeroNotix: it's not just about being high-level, it's about keeping things simple and separate in a way that makes sense.
19:03AeroNotixand they really make sense when creating your own types
19:04bitemyappThe point is that map and filter aren't the essence of FP. Nor are 1-degree-removed HOFs.
19:04technomancyAeroNotix: stop saying good things about haskell; he's trying to argue with you =)
19:05AeroNotixtechnomancy: oh I have plenty of disagreements with Haskell
19:05AeroNotixit's community being #1
19:05kristofThere's no limit on the order you can write a higher order function in clojure
19:05kristofAnd map, filter, and first class functions are in fact the essence of some value of FP
19:05technomancykristof: I've wondered what's the highest order of HOF ever seen in real-world code
19:05technomancywe should have a high-score board
19:06kristoftechnomancy: Doesn't matter, any good abstraction works for any degree-order
19:06hyPiRiontechnomancy: just apply some Y-combinators and get going?
19:06bitemyappkristof: it turns into a tarpit pretty quickly.
19:06bitemyappbecomes hard to debug, hard to write correct code.
19:06technomancyswap!+update-in+conj+fnil seems like a good starting point
19:06kristofbitemyapp: I'd appreciate some actual examples. I'm not being combative, I'm really interested in what you're saying.
19:07AeroNotixIs there nothing out there (or even if this is a sane approach) which uses type annotations in Clojure to deduce (some value of) correctness?
19:07bitemyappkristof: just learn Haskell. You'll figure it out in a hurry.
19:07technomancyI guess you still need one more as an arg to fnil
19:07bitemyappthere's no better way to understand my point.
19:07bitemyappkristof: then try to take what you were doing in Haskell with functors/applicatives/monads and do them in Clojure.
19:07kristofbitemyapp: came to Clojure from some newbie use of Haskell
19:07bitemyappkristof: then you'll realize you were standing on a sand castle.
19:07technomancybitemyapp: are you seriously arguing that combo I refered to above is difficult to debug?
19:07technomancyor are you talking about something else entirely
19:08kristofbitemyapp: The "sand castle" has not yet been discovered.
19:08bitemyapptechnomancy: something else.
19:08bitemyappkristof: learn more Haskell.
19:08bitemyappkristof: the epiphany probably didn't hit yet. It takes awhile.
19:08AeroNotixbitemyapp: you could easily write an applicative monad in Clojure, you just cannot prove it's correct.
19:08AeroNotixor at least typesafe
19:08bitemyappAeroNotix: what exactly is an applicative monad?
19:08bitemyappAeroNotix: do you mean an applicative functor?
19:08AeroNotixsorry yes
19:08kristofbitemyapp: I certainly plan on it but like I said, I'd really like an example of what you're talking about. The coolest example I can think of is the maybe monad.
19:09bitemyappAeroNotix: and how easy do you think it's going to be to write correct code in terms of those abstract interfaces without chewing through a bunch of type errors?
19:09AeroNotixbitemyapp: quite. The abstraction is still 'there' though, right? At least I still see the value in writing code like that.
19:09bitemyappkristof: that's not a great way to explain monads.
19:09bitemyappkristof: Maybe/Some/Option is as much about algebraic data types as anything else.
19:09kristofbitemyapp: Hrm.
19:09bitemyappkristof: you don't need monads for maybe. You can rely on ADT pattern matching or functors entirely.
19:09AeroNotixADTs are wonderful, though
19:10dnolenAeroNotix: you cannot prove monad laws in Haskell either, so there's no proof of correctness there either.
19:10bitemyapp`fmap (+1) $ Just 1` returns Just 2
19:10AeroNotixdnolen: true
19:10dnolenword to the wise it's best to ignore bitemyapp on this channel
19:10bitemyappAeroNotix: no, it's NOT
19:10bitemyappAeroNotix: you use quickcheck to verify monad laws in Haskell.
19:10noonianlol
19:10dnolenon anything to do w/ Haskell
19:10bitemyapppeople do it all the time.
19:10AeroNotixbitemyapp: not by the compiler, though
19:10bitemyappoh ffs.
19:10bitemyappso because the spaceship has one toilet instead of two you want to stay in a mud-hut?
19:10bitemyappfor real?
19:11AeroNotixc'mon
19:11AeroNotixso caremad
19:11kristofbitemyapp: You'll have to be more specific than "you're all living in a mudhut!"
19:11bitemyappkristof: so fmap is from the Functor typeclass, you can do anything you want with a Maybe wrapped value just with that.
19:11bitemyappkristof: monads are overkill for that.
19:12bitemyappkristof: better examples would be State in Haskell, Async in OCaml.
19:12kristofAsync in ocaml? Did you mean occam?
19:12bitemyappkristof: I can't really drop an easy to digest explanation in IRC if you don't understand the math or Haskell behind it. You're better off just getting the epiphany yourself.
19:12bitemyappkristof: I mean Async in OCaml. It's a library.
19:12AeroNotixDo you really need to understand math to understand fmap?
19:12bitemyappkristof: look at grenchman's source code.
19:12AeroNotixunless there was something else you wanted him to understand
19:13bitemyappAeroNotix: no.
19:13bitemyappfmap is pretty straight-forward.
19:13AeroNotixsure
19:13bitemyappit has the same type signature as map, it's just abstract instead of concrete, and specifically for Functors.
19:14bitemyappthe best way I can bake it down is in terms of typeclasses and type deduction for method dispatch.
19:14bitemyappFluokitten's use of protocols might demonstrate some of it.
19:14AeroNotixhm
19:14bitemyappkristof: AeroNotix - https://github.com/uncomplicate/fluokitten
19:14bitemyappso, they're basically using protocols to solve the type deduction and dispatch thing
19:14kristofType inference is cool, I'll give static typing that.
19:14bitemyappbut it's not really composable or type-checked the way typeclasses are.
19:15AeroNotixnext up: Go's type system
19:15bitemyappit also can't really help with the composition of multiple protocols and help you stay sane.
19:15bitemyappGo's type system is pointless. Why even bother?
19:15kristof^
19:15AeroNotixwas a joke
19:15bitemyappso the point is that in Haskell, you can (safely) write code in terms of composing things from different typeclasses
19:16kristofbitemyapp: So what you're saying is that protocol dispatch on type is flimsy without typeclasses and some form of single/multiple inheritance.
19:16bitemyappkristof: you don't need inheritance, but yes.
19:16bitemyappkristof: you can compose without inheritance.
19:16kristofWell, that's what typeclasses are kind of for, aren't they?
19:16kristofThis is a that
19:16kristofThis is an Ord
19:16kristofand a Num
19:16kristofetc.
19:16bitemyappyeah but they're independent.
19:16bitemyappthose specific ones are.
19:16kristofSo?
19:17kristofClasses can be independent
19:17bitemyappSuperclassing is a thing - people have been trying to turn Monad into a superclass of Applicative for awhile
19:17bitemyappso that the relationships are more clear and match the category theory more directly.
19:17bitemyappbut it doesn't harm anything.
19:17kristofbitemyapp: I'm really think about generic functions and multiple inheritance in Common Lisp
19:17bitemyappkristof: ick, you can do better than that by far.
19:17kristofOh, probably, but it's certainly a step above Clojure protocols
19:17bitemyappRust traits, Scala traits, and Haskell typeclasses are a better way to do it.
19:18kristofbitemyapp: when's rust 0.9 out?
19:18bitemyappkristof: yeah, I think I'd agree with that, but I was an AOP'er in CL.
19:18bitemyappkristof: now.
19:18kristofWoah! Hold the phone! :P
19:18kristofbitemyapp: AOP?
19:18locksaspect-oriented programming
19:18seangrove~aop
19:18clojurebotI don't understand.
19:18locks?
19:18kristofOh, I see
19:19seangroveclojurebot: aop is Aspect-oriented Programming http://en.wikipedia.org/wiki/Aspect-oriented_programming
19:19clojurebotOk.
19:19seangrove~aop
19:19bitemyappkristof: metaobject protocol stuff.
19:19clojurebotaop is Aspect-oriented Programming http://en.wikipedia.org/wiki/Aspect-oriented_programming
19:19bitemyappkristof: I do the same in Clojure occasionally with dire/robert.hooke
19:19locksis this channel always this caremad?
19:19bitemyappI don't think bringing 4chan jargon into this channel improves anything - can we drop that word?
19:20kristoflocks: I coerced bitemyapp into having cordial discussion, no harm in that
19:20bitemyappit implies that you should be detached from everything you say and that seems a poor way to communicate with others.
19:20bitemyappinsincerity ain't a good thing.
19:20kristofThe internet is at stake, after all
19:20kristof:P But yes, discussion is important and I think it's healthy for any language community
19:21lockswhat I’ve seen isn’t discussion
19:21bitemyappit's also how a lot of knowledge gets propagated in programming language communities.
19:21locksit’s “everything sucks"
19:21bitemyapplocks: well, I don't think you're obligated to be here.
19:21locksliterally even, a couple pages up
19:21kristoflocks: Everything does suck!
19:21bitemyappyou could go make a sandwich.
19:21kristofI'm about to fix myself a sandwich, actually.
19:22locksbitemyapp: oh, nice
19:22bitemyapplocks: if you're satisfied, you're not looking hard enough.
19:22locksyes I will leave because I won’t put up with your passive aggressiveness
19:22bitemyappgood way to blub it up.
19:22alewwhen writing clojure macros that involve functions included from other namespaces, should you unquote them?
19:22technomancyalew: just look at the macroexpansion
19:22bitemyappalew: you mean fully qualify them?
19:23justin_smithalew: quasiquote already does the full neamespace expansion
19:23kristofbitemyapp: if you're on haskell or here regularly, I'll pester you sometime, thank you for piquing my interest again with opinionated combative behavior
19:23hyPiRion,`(+ 1 2) ;; alew
19:23clojurebot(clojure.core/+ 1 2)
19:23bitemyappkristof: no problem. I give Haskell tutorials periodically in person and over the internet so if you need any help with anything please ping me.
19:23bitemyappkristof: I'm always online but not necessarily at my terminal. I see my logs.
19:24kristofbitemyapp: I will. My biggest problem with Haskell was the bondage and discipline, but it's not without justification.
19:24alewright, it namespace expands them, but if that macro is used in another namespace, there won't be any issues?
19:24bitemyappkristof: hum. Usually if it feels BDSM-y you might be going about things the hard way.
19:25justin_smithalew: if the defining namespace requires the ns in question, it is available if fully ns qualified, it all just works
19:25bitemyappkristof: one of the better ways to break out of that when you want to "say less than things actually are" is Lens.
19:25bitemyappespecially to handle non-deterministically structured data.
19:26justin_smithalew: it would break if the macro uses an ns that its own file does not require, but then again that would break down at ns qualification time when compiling
19:26noonianalew: syntax quote namespace expands things in the namespace that the macro is written in which will have required the relevant namespaces so it's all good
19:26bitemyappkristof: I prefer the BDSM compiler errors to the long tail of unnecessary type errors/stack-traces. That's subjective I s'pose, but I am legitimately more productive over a given period of time that way, not just preferentially.
19:26kristofOh, no, I wasn't talking about static typing
19:26kristofIt was with regard to state in general
19:27alewwhat about with java imports? those don't seem to be qualified
19:28bitemyappkristof: I think that comes with grokking the typeclassopedia really.
19:29bitemyappkristof: having pure/impure functions decomplected is pretty nice and monads let your side effects and state be introspectable, typed values instead of magic aetheria.
19:29bitemyappkristof: I don't recall having any trouble firing off side effects at will.
19:29bitemyappkristof: that might be awkwardness around not knowing how to write valid monadic code.
19:29bitemyappI had the same problem earlier on.
19:30bitemyappbut again, I'd rather get smacked on the nose called a bad puppy for writing incorrect code.
19:33Raynesbitemyapp: I listened to the entirety of Visions and only realized it because I noticed the music stopped.
19:34RaynesMe not realizing I'm listening to music for 45 minutes isn't a good sign
19:35bitemyappRaynes: a good sign for the music or your dehydration?
19:35RaynesFor the music :p
19:35bitemyappRaynes: you're used to really rambunctious stuff.
19:36bitemyappwith clear, loud, proud vocals.
19:36bitemyappRaynes: Grimes is this spooky chick with a tape recorder from the 80s and a garage sale keyboard.
19:36RaynesIndeed.
19:39arrdemif I notice that the music is there, it's doing its job wrong.
19:39arrdemwhite noise ftw.
19:39nooniandnolen: is this an appropriate way to nest components in om or is this not a good idea to do? For example (om/build my-c app {:opts {:content (om/build my-c2 app {})}})
19:40lsdafjklsdnoonian: why not
19:41noonian /shrug, it just doesn't feel intuitive
19:42lsdafjklsdnoonian: yea, it doesn't look great just looking at it, but there is no context
19:42Tolstoynoonian: That doesn't seem right at all. Aren't ops for passing in small "configuration" settings for the my-c component?
19:42stcredzeroIn Rich Hickey's ant simulation, I keep seeing things like (send-off *agent* #'animation) in timing loops. What is with *agent*? Do those asterisks mean something, or is it just a different method name?
19:42lsdafjklsdtolstoy: well you can pass dynamic view in the ops
19:42lsdafjklsdtolstoy: he does that in an example
19:43hyPiRionstcredzero: That's old examples, but *name* means that the variable is dynamic
19:43technomancystcredzero: it means the agent running the current code
19:43Tolstoylsdafjklsd: Ah, okay.
19:43justin_smithstrax: method? - *agent* is just a name for a var
19:43noonianlsdafjklsd: which example?
19:43alandipertstcredzero: the 'earmuffs' indicate in lisp a dynamic or mutable variable
19:44justin_smithnaming dynamic bindings with *name* is a convention, but is not enforced at all
19:44hyPiRionand technomancy beat me to the second part
19:44stcredzeroSo it's just a convention, not some kind of sigil?
19:44noonianTolstoy: its either in the ops or in the cursor for the app state right?
19:44hyPiRionstcredzero: yeah, just convention, but you'll get warnings by default if you don't follow it
19:44justin_smithright, a naming convention
19:45Tolstoynoonian: Alas, I always tend to try to keep things simple. I'd rather pass in an option, then use a "cond" or whatever to decide what to do.
19:45hyPiRion,(def *foo* nil) ;; e.g.
19:45clojurebot#<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>
19:45lsdafjklsdnoonian: the sortable example
19:46justin_smith,(do (def *thing* 1) (def *what* 2) (+ *thing* *what*))
19:46clojurebot#<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>
19:46noonianlsdafjklsd: thanks
19:46lsdafjklsdnoonian: (om/build sortable app {:opts {:view item}}))))
19:46justin_smith&(do (def *thing* 1) (def *what* 2) (+ *thing* *what*))
19:46lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
19:46justin_smithhmm
19:46lsdafjklsdnoonian: item is an om/component
19:46noonianTolstoy: it'd be nice to be able to write reusable component libraries though so you couldn't know ahead of time what to do in the different cases
19:47robonerdin the context of web app dev (+ client/mobile/etc would only be a bonus), does anyone happen to know of a language similar to ruby, but perhaps slightly tightened up? (eg, [opt-in] static typing, of which so far i've found erlang and racket)
19:48alewclojure has opt-in static typing
19:48alewsort of
19:48robonerdplease explain?
19:48noonianlsdafjklsd: but there he builds it in the component he passes it to, which then needs to know about the interface for the item right?
19:49alewhttps://github.com/clojure/core.typed
19:50lsdafjklsdnoonian: yea, it just get's wrapped in the functionality of sortable so not exactly as decouple as what you're trying to do
19:50robonerdin the context of web app dev (+ client/mobile/etc would only be a bonus), does anyone happen to know of a language similar to ruby, but perhaps slightly tightened up? (eg, [opt-in] static typing, of which so far i've found erlang and racket) ideally, on the topic of opt in typing i want to not only be able to say some property is an array, but say it's an array with only string elements.
19:50robonerdthere, updated
19:51alandipertnoonian: have you given hoplon.io a peep? our goal is modularity and to do it we separate the app state machine from the rendering via 'cell' ref type
19:51hiredmancore.typed is based in some part on typed racket
19:51alandipertnoonian: a similar approach might be possible using om but i haven't tried
19:52lsdafjklsdin react cant you render into components through mounting?
19:52arrdemhiredman: in large part...
19:52lsdafjklsdi've been meaning to look into that
19:52dyresharkrobonerd: if you can deal with full static typing, F# is pleasant, runs on Windows/WP and OS X (with Mono, which is decent). Also, it has Xamarin for porting directly to iOS/Android. (Xamarin website advertises C#, but they have plugins for F# dev IIRC)
19:52hiredmanand it can type collections just fine
19:52dyresharks/OS X/Anything supported by mono/
19:52noonianalandipert: thanks for the link, i'll check it out
19:53robonerdin the context of web app dev (+ client/mobile/etc would only be a bonus), does anyone happen to know of a language with [opt-in] static gradual typing? ideally, i want to not only be able to say some property is an array, but say it's an array with only string elements.
19:53robonerd(updated)
19:53dyresharkok :p
19:53technomancyrobonerd: this isn't a forum, geez
19:53hiredmanstop updating please
19:53robonerdoh sorry
19:53Tolstoyrobonerd: Groovy? ;)
19:54xuserrobonerd: Dart
19:54hiredmananyway, you've gotten plenty of responses
19:56robonerdloaded them up, will reearch now, ty
19:56robonerdbtw does clojure have this feature?
19:56robonerdah, loading core.typed now
19:57hiredmanhe must irc via email
20:00bitemyapprobonerd: if you want full static typing with FP give Haskell a shot!
20:01bitemyapprobonerd: the types are organized around typeclasses, and the functions are abstract/polymorphic by default rather than concrete by default.
20:01bitemyapprobonerd: so a relatively common function signature would be things like a -> b or a -> a with some relevant typeclass qualifier than having to go to extra trouble to make your functions reusable.
20:03bitemyappMakes doing things the right way lower friction.
20:04arrdem$google haskell javascript compiler
20:04lazybot[The JavaScript Problem - HaskellWiki] http://www.haskell.org/haskellwiki/The_JavaScript_Problem
20:05bitemyapparrdem: Fay, GHCJS, Haste.
20:05dyreshark^ Also, as much as it's considered good practice to add explicit type information in Haskell for functions, most types can be inferred for you by the compiler if you're feeling lazy ;)
20:05arrdembitemyapp: yep.
20:05bitemyappdyreshark: I use the inference to "query" what my code is doing. Very informative.
20:05bitemyapparrdem: things that aren't Haskell but are similar that compile to JS include: PureScript and Roy.
20:06bitemyappthe most practical option right now is Fay.
20:06bitemyappand that's what I use.
20:06bitemyappFPComplete has about 10k+ LOC of Fay in their frontend at the moment.
20:06bitemyappTypes are shared directly with the backend.
20:06arrdemJavascript: not an acceptable PL, acceptable compile target. wat.
20:07technomancy* if you don't need integers
20:07bitemyapptechnomancy: uh, mostly. |0 is guarantee to return an integer.
20:08bitemyapptechnomancy: so if you annotate the results of all numeric operations with that, it's integers all the way down modulo precision loss.
20:08bitemyappasm.js understands it.
20:08technomancybitemyapp: precision loss is what I mean
20:08bitemyapptechnomancy: oh yeah, that part sucks but that's what asm.js is for.
20:10bitemyapptechnomancy: asm.js compatible VMs will turn the operations into integers specifically.
20:10alewis there a good way to avoid increasingly nested conditionals for handling complex validation? specifically in web handlers
20:10technomancysure, nice if you can assume it's there
20:12alews/avoid/refactor/
20:12arrdemalew: dire's postconditions/preconditions could be useful...
20:12bitemyappalew: Monoids!
20:13arrdembitemyapp: quiet you.
20:13bitemyappI'm serious :(
20:14alewI'm not super familiar with dire, but from what I gathered it doesn't give much benefit for one off conditionals?
20:14alewI'm probably off here
20:15bitemyappalew: dire's fine if it's a match for what you want. Monoid Validator + Writer/Error is one way to do it "scalably" with sensible error messages.
20:15arrdemI mean if you are truly faced with a raft of disjoint, once-off conditionals there's nothing that can really help you. Any refactoring approach or tool will rely on commonalities or common sub-conditions.
20:16alewI guess I should just break them out into internal helper functions
20:18bitemyapparrdem: if they're separated by space and time then you can use Monads...
20:18arrdembitemyapp: I suppose -> [ a:Value, b:Err ] with short curcuiting would be a monoid...
20:18bitemyappalew: Monoids let you aggregate a super-conditional, monads let you sequence functions against the value with sensible validation/error output as needed after/before the operations without repeating yourself.
20:18bitemyappthere are many options here!
20:19alewWell I'm using clojure, so monoids might not be the most idomatic approach here
20:20ehabsAfter profiling some code, I found out that walking lazy seqs is a big performance bottleneck in one of my functions. The problem is that running doall on it causes a stack overflow. Whats the best way for me to handle this?
20:20steeriowhy do you need the doall?
20:21ehabsbecause i don't want to re-walk the seq over and over again. or am i misunderstanding something?
20:21steeriore-walk as in?
20:21arrdemehabs: need code to comment. refheap please.
20:21steeriothe seq gets realized the first time you walk over it. whether the head gets retained depends on your code.
20:22steerioif the sequence is too large for your memory, however, it's your heap that gets blown, not your stack
20:22alewmaybe your lazy seq is infinite, that would blow the stack
20:23alewor actually no
20:23steerioit wouldn't, that'd be the heap
20:23ehabsjust a minute. i'll post the code for you to check out. i'm sure it isn't infinite because it evaluates as expected when its lazy. its just extremely slow
20:24steeriocan you paste the actual output when that overflow happens?
20:24steerio(along with the code)
20:25ehabshere is the code: http://pastebin.com/45aweM15
20:26arrdem(dec pastebin)
20:26lazybot⇒ -1
20:26arrdem~pastebin
20:26clojurebotTitim gan éirí ort.
20:26arrdemclojurebot: you have failed me for the last time commander
20:26clojurebotHuh?
20:27ehabssorry, i haven't used refheap before. i'll try to use it next time
20:28ehabshttp://pastebin.com/gpuEa652
20:28steeriocan you see the repeating pattern in the stack trace?
20:29steerioin fact your problem has nothing to do with the fact that you deal with lazy seqs
20:30steeriothere's simply endless recursion somewhere in there
20:30arrdemsteerio: it may be bounded, just bigger than stack size.
20:30ehabslet me see what i changed. it definitely ran for me a minute ago
20:31steeriothat's true, just unlikely
20:33ehabsthis code runs without a stack overflow: https://www.refheap.com/22773
20:35steerioi'm a bit too tired to diff them now
20:35steerioalso, they contain quite some references to functions that you define but are not included
20:37steerioany of them could easily be the culprit
20:37ehabsdo you have any advice on what i should look for?
20:37steerioanything that ends up in a circular call
20:38shep-homeehabs: are you running all of that code in the REPL?
20:38ehabsyes
20:39shep-homeyou might want to put some of it into a different namespace - that would help the stacktraces identify your code
20:42steerioin fact there's nothing in the visible stack trace that's not from core
20:42shep-homesteerio: good point, I was just scanning for something different..
20:43shep-homeIs it possible to have created a circular structure of some type?
20:43shep-homes/to have/that ehabs has/
20:44ehabsi don't think i do. the code works exactly as expected if i use a subset of the data
20:44ehabsthe problem is when its using 12,000 data points
20:45steeriowhich is weird.
20:45shep-homeehabs: the only difference in the code is adding `vec` to the apply?
20:45steerioif it was a head retention problem, you'd blow the heap, not the stack
20:46steerioas far as lazy sequences go, they don't care how many items you end up having in them
20:46shep-homeI wonder if you are just realizing something now that you weren't before
20:46ehabsyes that is correct. taking vex out causes it to blow the stack
20:46shep-homeoh, taking it out...
20:46ehabs*vec
20:50steerioso what does seq-without-nth look like?
20:50steerioi think i'm starting to see what's going on here
20:51steerioyou're basically creating lazy seqs of lazy seqs of lazy seqs...
20:51steerioso you're doing operations on sequences that yield lazy seqs in a depth proportional to your data size
20:51steeriowhich is all fine until you realize it
20:51steerioand then you blow the stack because it's so deep
20:52steerioimagine (map #(map #(map ....
20:52steerioin a 12k level depth
20:52steerioyour call on vec is a way out of it because it realizes the given depth and frees you from one level of calls whenever you do it
20:53ehabshere are the other two helpers used in the let: https://www.refheap.com/22774
20:54ehabsthe data is shaped like: X= [{1 float 2 float 3 float 4 float 5 float}...] and Y=[zeros-and-ones]
20:55steeriolet me just illustrate you what i'm talking about
20:55shep-homesteerio: so it could be "fixed" by only realizing a bit at a time, but there's still a timebomb waiting...?
20:55steerio,(reduce (fn [s _] (map identity s)) (range 12000))
20:55clojurebot#<StackOverflowError java.lang.StackOverflowError>
20:56steerioin fact the buildup of lazy sequences should be identified and eliminated
20:56steerioperhaps by a different algorythm, perhaps by realizing every step
20:57ehabscan you see where the buildup is happening?
20:57steerioyour code is way more complex than what would allow me to see that at 3am
20:57steerio:D
20:59steerioin such situations what happens is that you repeatedly do some operation over elements of a collection
20:59steeriowhich in most cases can be refactored into one operation
21:00steeriolike: (map inc (map inc (map inc coll))) is equivalent to (map #(+ 3 %) coll)
21:00steerioin this case you are thousands of level deep in the "(map inc (..."
21:00steeriogranted, it's more complex than this example
21:01ehabsyeah, that makes sense. too bad it isn't that obvious in this case
21:01steeriostart taking apart this huge functions into smaller ones
21:02kristofIf it has over 5 levels of nesting...
21:02steerioand testing and comprehending what they do one by one, and you'll probably end up finding it
21:02kristofAh, how does that joke go again...
21:02kristof"How do you know when a function or method gets too big?" "When it's bigger than my head." "You mean when it's too conceptually large?" "No, I LITERALLY put my head against the monitor."
21:04ehabshaha yeah, i definitely need to do that. the top part of the cross validation function is seems to be where the problem is and that can easily be broken out into small pieces.
21:06steerioehabs, check this
21:06steerio,(class (flatten [1 [2 3] 4]))
21:06clojurebotclojure.lang.LazySeq
21:06steerioflatten yields a lazy seq. now, you're storing these as values in a hash
21:06steeriothen you probably at some point repeat this operation and nest lazy seqs at a huge level
21:07steerioas you merge hashes and whatnot
21:08steerioevery merge-with just nests those lazy seqs even more
21:08steeriowithout actually doing any flattening
21:08steeriothe (vec) call realizes them at each level to create that vector out of them
21:09steeriothereby saving you from this nesting
21:09steerioin fact probably everything goes fine and dandy until your REPL tries to _print_ the insanely nested lazy seq
21:12ehabsyeah, that makes sense. thats definitely what its doing. i just don't see how it would get deep enough to matter in this case. i'm running it with only 10 groups, so it would at most be 9 levels deep.
21:12steerioremember that pretty much every operation you do on a collections yields a lazy seq
21:13ehabsyeah, thats true. i'm starting to visualize it now. is the solution to just start running doall on them or convert them to vectors? or is there a better way?
21:14steerioand in your case, if you merge two hashes with the same keys, all the values have just become at least one more level deeper nested
21:14xuserd
21:14steerioand all those hashes have the same keys, :training and :testing
21:15steerio(which begs the question of why you don't use a two-element vector for this)
21:15steerioalso, partitioning data can be done more efficiently too
21:16steeriosame goes for the :x/:y map, use a vector
21:16steerioso your data becomes [x y] instead of that (map #(hash-map ... thing
21:17gtrakI've missed it when other folks have talked about it, is 'austin' the most full-featured cljs repl? I'm hoping for some autocomplete love.
21:17steerio(get-in [:training :x] foo) becomes (first (second foo))
21:18ehabsyeah, that makes sense. but that still doesn't solve the issue with most of the clojure functions returning lazy seqs. whats the best way for me to avoid that?
21:19steerioa better algorythm :)
21:19steeriothis normally isn't a problem
21:19steeriowhile in a non-lazy lisp this would not blow your stack, it'd be really ineffective
21:20steerioas you'd traverse collections 12k times, instead of writing less functions that do it in one step
21:23bitemyapparrdem: doters?
21:25ehabsok, i'll make the changes that you mentioned. thanks for the help steerio
21:25steerionp
21:26steerioin fact even using vector tuples instead of the hashes eases up on this
21:27steeriowell, maybe even solves it
21:29ehabsok, thats the first change i'll make
21:31hiredman /win 26
21:46logic_progin clojure, is it possible to construct an object where (1) it supports all operations of map and (2) can only be constructed by a certain function
21:47logic_progi.e. I want "(my-magic-foo ...)" to be the only way to construct a special map
21:48alandipertlogic_prog: check out def-map-type in potemkin, https://github.com/ztellman/potemkin
21:49logic_progalandipert: this is interesting, let me look into this
21:50noonianlogic_prog: sounds like records might be what you want
21:50sritchienoonian: I think logic_prog wants to hide the constructors
21:50noonianah
21:50logic_progyeah, I want guarantee that a function was only created via (my-magic-foo ...)
21:51logic_progs/function/map
22:04logic_proghow can I check if something is a core.async.chan ?
22:04logic_progerr, clojure.core.async/chan
22:06gtrakseems like they all may extend clojure.core.async.impl.protocols/Channel
22:06gtraksatisfy, rather
22:07gtrakbut.. one way to know is to try to use it as a channel :-)
22:07gtraksurely that'll fail.
22:07logic_progI'm surprised there's no (chan? ...) function
22:08noonianme too
22:08logic_proggreat wizards of clojure,
22:08logic_progfix the above please
22:08logic_progadd a (chan? ..._) to clojure.core.async
22:09gtrakseems harmless enough
22:10gtrakI'm trying to get a dump of the cljs analyzer state, massive rabbit hole
22:11gtrakfrom hacking cljsbuild
22:20abplogic_prog: There was a ticket for it: http://dev.clojure.org/jira/browse/ASYNC-12
22:21logic_prog(defn chan? [c] #+clj (= (type c) clojure.core.async.impl.channels.ManyToManyChannel) )
22:21logic_proglooks sorta ugly
22:24arrdembitemyapp: just got back from a barbeque outing. hopping on.
22:27bobajetthi folks, Im wondering why in Perl/Ruby split("foo", "") -> ["f","o","o"] and in clojure (str/split "foo" #"") -> ["","f","o","o"]?
22:29andyfbobajett: Clojure's split is based on Java String class split, and that is the way Java String split works.
22:29bobajettandyf: gotcha. Thanks!
22:30amalloybobajett: i can't speak for ruby, but clojure of course just delegates this to java. and java asks "where is the first match of #"" in this string? okay, it's before all the characters. i'll return a match there. now where's the next? after f, all right, return a match there..."
22:30TEttingerbobajett, there's also ##(vec "fpp")
22:30lazybot⇒ [\f \p \p]
22:30TEttingerbut that returns chars
22:30amalloythat's as sensible an interpretation of "split on [nothing]" as ruby's
22:30TEttingeror ##(mapv str "foo")
22:30lazybot⇒ ["f" "o" "o"]
22:31noonianis there an empty string on either end of "foo"?
22:31bobajettamalloy: :-) cool thanks for the detailed explanation
22:31amalloyTEttinger: (seq "foo") seems nicer than vec
22:31noonianseems like theres actually any number of them
22:31bobajettnoonian: yeah thats what I was wondering too
22:31TEttingeramalloy, yeah, that too
22:31hiredman,(.charAt "foo" 0)
22:31clojurebot\f
22:32bobajettTEttinger: sorry Im only very early in my learning clojure career what do the two ## mean in ##(mapv str "foo")?
22:32lazybot⇒ ["f" "o" "o"]
22:32TEttingerjust a command to execute the bot's eval
22:32amalloynoonian: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#split(java.lang.String,%20int) says some things about "trailing empty matches", but the sentence is hard for me to follow
22:32TEttingersame as starting a line in IRC with ,
22:32bobajettah got it thanks.
22:33andyfnoonian: If you want to get all splits, including the trailing ones, give a negative integer as a 3rd arg
22:33amalloy&(.split "foo" "" -1)
22:33lazybot⇒ #<String[] [Ljava.lang.String;@9ffba4>
22:33amalloy&(seq (.split "foo" "" -1))
22:33lazybot⇒ ("" "f" "o" "o" "")
22:33logic_progin cljs, how can I check if an object is an atom, a string, or a cljs.core.async ?
22:34andyfSeveral examples available here that might be more instructive to read through than to try to give general rules: http://clojuredocs.org/clojure_core/clojure.string/split
22:34TEttingerso (mapv str "foo") will take "foo", and for each element (a character), return the result of calling str on it "f" "o" "o", and then make it a vector (not a lazy seq as for map, which may be preferable or not)
22:36bobajettTEttinger: got it thanks. I could guess what (mapv str "foo") did, but didn't know what the two ## were for.
22:37bobajett##(class "foo")
22:37lazybot⇒ java.lang.String
22:37TEttingerbobajett, heh it's an odd shortcut for the bot to use, since #(* %1 %1) is an anon fn that will multiply an argument by itself
22:38TEttingersame as (fn [n] (* n n))
22:39bobajettTEttinger: isn't the reader macro for creating a set also start with a "#" ?
22:39TEttingeryes
22:39TEttinger# is a dispatch char
22:39TEttingerit changes what comes after it
22:40TEttinger#() is a fn, #{} is a set, there are a few others
22:40TEttingerI believe one causes a form to be ignored, can't remember what it is
22:40bobajettlogic_prog: I shouldn't be answering this, since my clojure knowledge only some days old, but maybe (class yourObject) ? and compare it with java.lang.String or java.lang.Long or some such?
22:41logic_progbobajett: good try, but I need it to work in cljs
22:41TEttingerbobajett, that would definitely work on JVM, but maybe it doesn't on CLJS aaaagh
22:42bobajettTEttinger: '("foo" #_(elide this stuff) "bar")
22:43TEttingerbobajett, seems like that's one of them. I believe #> also gets elided, it came up earlier
22:44amalloywat
22:44bobajettTEttinger: ah did not know about that one. don't see it on the cheatsheet.
22:44amalloy,'(x #> y)
22:44clojurebot#<RuntimeException java.lang.RuntimeException: No reader function for tag >>
22:44amalloythat doesn't work in any version of clojure
22:45bobajett,'(x #_y z)
22:45amalloyas far as i know
22:45clojurebot(x z)
22:45TEttingerit was one of the reader macros on that one thing earlier today
22:47bobajettthanks folks, I was trying to do regex splitting and noticed Perl/Ruby behaved differently and Python behaved differently and Clojure behaved differently. #clojure is where I found the most helpful people :-)
22:51logic_proggiven an object
22:51TEttingerhttp://sprunge.us/GbOX?diff
22:51logic_progis there a easy way to list all protocols it satsifies/implements?
22:52tbaldridgeno, but you can list all objects that extend a protocol
22:57bja_logic_prog, maybe something involving #(.keys js/Object %)?
22:57bja_err, maybe not.
22:57bja_cljs$lang$protocol_mask$partition0$ doesn't look super helpful
23:03gtrakcemerick: would you balk at an autodoc sort of thing in lein-cljsbuild? I managed to make it dump the analyzer output, now I want to see if I can grab what I need to build something like that.
23:05gtrakI'm also thinking auto-complete eventually, not sure if that's the right approach, but just trying stuff :-).
23:05cemerickgtrak: Not sure. Open an issue when you're closer. :-)
23:05gtrakcool
23:13logic_progwhat are the names of the protocols that string, number, atom implement ?
23:19gtraklogic_prog: huh?
23:19logic_progin clojure, everything implements some protocol right?
23:19logic_progwhat protocols do string, number, and atom objects implement?
23:20gtraknot necessarily, plus some of those are java interfaces
23:20gtraklike IDeref
23:20tbaldridgeclojure or clojurescript?
23:21tbaldridgein clojure, most things are backed by java interfaces
23:22gtrakholy jesus, the serialized output of the cljs compiler is massive
23:22gtrakI mean the state
23:23tbaldridgeyeah....it will be
23:23tbaldridgethere's a ton of structural sharing
23:24tbaldridgeso the same hashmap will extist on almost every ast node
23:24gtrakin general are there libs that walk it? trying to simply extract 'vars' and metadata and such.
23:24gtrakI could do it in-process, but was hoping to just dump it :-)
23:25tbaldridgeyeah, it's not really dump-able. You want to do it in process
23:26tbaldridgealthough you might be able to strip the :env nodes before export. That's where 99% of the bulk is, and it's not really needed
23:30gtrakI might resort to inspector.clj :-)
23:30gtrakI've used that like once.
23:30andyfgtrak: I've used the inspector quite a bit for looking at output data from tools.analyzer(.jvm)
23:30tbaldridgejust use prewalk and post walk
23:31andyfgtrak: It does not show metadata, unfortunately
23:31gtrakah
23:31tbaldridgeand metadata isn't really used by the cljs compiler
23:31gtrakyea, metadata seems silly, the whole thing is metadata
23:32logic_proghttps://github.com/clojure/clojurescript/search?p=2&amp;q=swap%21&amp;type=Code <-- where is swap! defined ?
23:32tbaldridgehttps://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L7081
23:32tbaldridgeThat's swap! ^^
23:32andyfgtrak: I wouldn't use it for looking at analysis results of large source files, but worked OK for me for small to medium source files.
23:35logic_progtbaldridge: https://github.com/clojure/clojurescript/search?q=defn+swap%21&amp;type=Code <-- how should I be searching for taht instead?
23:36tbaldridgemost stuff is in that single file, I'
23:37tbaldridgeI've never really used github search
23:37amalloylogic_prog: just look in the file that it "should" be in - the cljs source is organized pretty predictably. i have no experience with github code search, but it sounds like it's not that useful
23:37logic_progamalloy: I'm getting started, "should" means nothing to a newb with no intuition
23:37logic_proghowever, grep seems to work
23:38amalloylike tbaldridge says, most functions from cljs.core are in that one file
23:38amalloymacros are all in another file somewhere
23:38RaynesYay for shoving everything in a giant file!
23:39tbaldridgeat least it's easier to find.
23:39tbaldridgeI really don't have a problem with putting it all in one file
23:43KeithPMGood day. I am having a few problems with a function to generate permutations. I created a gist here https://gist.github.com/kpmaynard/8367053. I have some commentary at the top but I am currently running in to two errors in LightTable (permx '(1 2 3)) is generating the following errors
23:43KeithPM at recursion$permx.invoke(/Users/kpm/dev/clojure/recursion/src/recursion.clj:262)
23:43KeithPMin the status window
23:43KeithPMand
23:43KeithPMclojure.lang.ArityException: Wrong number of args (0) passed to: recursion$permx
23:43KeithPM AFn.java:437 clojure.lang.AFn.throwArity
23:43KeithPM AFn.java:35 clojure.lang.AFn.invoke
23:43KeithPM
23:43KeithPMIn the REPL
23:44gtrakeek, don't paste multi-lines like that
23:45KeithPMWould you prefer that to be on one line?
23:45gtrakwell, here's the relevant single line: clojure.lang.ArityException: Wrong number of args (0) passed to: recursion$permx
23:46KeithPMgtrak: I am calling the function (perms '(1 2 3)) That looks like one argument to me right?
23:47gtrakpermx is the breaking one
23:47KeithPMOK… Maybe in the recursive calls?
23:48gtrakseems like you didn't evaluate something before running it
23:48gtrakso, it's running an old version of the function or something like that
23:48KeithPMI think I know why… Looks like when the seq is a singleton, rest is nil...
23:48KeithPMLet me take a look at that
23:48gtraknil is still an arg
23:48KeithPMOK
23:48KeithPMHmmm
23:48gtrakso.. it's whatever's calling that in the first place most likely
23:49TEttingerKeithPM, are you sure your parens line up?
23:50KeithPMTEttinger Hmmm… I think so, I have pretty much cleared out the repo and the file compiles OK
23:51TEttingeryeah, it's just the indents were at different levels in the gist
23:51TEttingernvm just checked
23:54KeithPMTEttinger: OK.
23:55KeithPMgtrak: The first call is being made in the instarepl
23:55TEttingeralso I think you may be using nil incorrectly: ##(nil? [])
23:55lazybot⇒ false
23:55hansel-hanWhat could I use to get a set where values have a TTL?
23:55TEttingerhansel-han, like an expiration date?
23:56hansel-hanTEttinger: it's for a Who's Online box on a forum. yeah. users get conj'd when they do click around on the forum but fall off when inactive for 5 minutes.
23:58amalloyhansel-han: i've used a sorted-map of {timestamp, value}
23:58TEttingerI'd use something like overtone/at-at and schedule an event to delete users who have are inactive for 5 minutes, resetting on action
23:58KeithPMTEttinger: Do you mean in permx? RH says when there is nothing left in a sequence clojure returns nil not ()… I therefore test for nil? not empty? Is that a problem?
23:58hansel-hanI've never used core.cache but I see it has a "TTLCache". Perhaps that's an option?
23:59amalloywith such a sorted map, you can easily say "remove all entries whose keys are less than x", and updating someone's timestamp is just dissocing them and re-associng to the current timestamp
23:59TEttingerKeithPM, kinda. the preferred idiom is using seq to test for non-emptiness, which returns nil on an empty seq and the seq otherwise.
23:59TEttinger,(seq [1 2 3])
23:59clojurebot(1 2 3)
23:59TEttinger,(seq [])
23:59clojurebotnil
23:59amalloyusing scheduling or a cache sounds like a lot of work, and less predictable (timing-wise) than doing it yourself