#clojure logs

2014-03-01

00:56muhoohttp://www.youtube.com/watch?v=vWNJlc-IylY
00:58nopromptmuhoo: this is awesome. just what i needed right now. :)
00:59muhoonp, glad to be of help
01:04noprompti'll share a fun one too.
01:04noprompthttp://www.youtube.com/watch?v=0ObNPZy40Zw&index=10&list=LL5nj8P53p55J6VNR8STWR7A
01:06SegFaultAXAnd here's an old classic that always makes me happy: https://www.youtube.com/watch?v=uq-gYOrU8bA
01:06nopromptwhat the hell happened to good music?
01:07nopromptdamn kids these days. no taste.
01:07noprompthaha.
01:07nopromptwhat the hell happened to bass lines?
01:07SegFaultAXAll the good music passed through the music industry human centipede-style.
01:08SegFaultAXAnd came out the other end... well, you know.
01:08goldfeldcellphones and crappy earbuds happened to bass lines
01:09nopromptoh and lyrics are pretty much dead sauce too. :(
01:09goldfeldalso previous generations had more of a cult of the car, which is somewhere you could sport a good soundsystem, in that sense at least it's a good thing to have happened to kids these days
01:10goldfeldi'd say i'm close to a kid depending on where you're coming from, and there's little from the past two decades which i listen to and whole lot from before that
01:11SegFaultAXYou know what I wonder sometimes? Where are the Shakespeares and the Michelangelo's of our day?
01:11nopromptSegFaultAX: they're writing code.
01:11SegFaultAXIt's like we're not generating enough great artist points per turn anymore. Or the threshold has gotten so high, they almost never spawn.
01:12goldfeldSegFaultAX: they're in heavy debt and without a job, and the age of patronage of artists is well over
01:12SegFaultAXgoldfeld: Oh, so that's who made my latte this morning...
01:12goldfeldSegFaultAX: there's a non-zero probability in that
01:13nopromptit's also worth mentioning the general lack of focus on art.
01:13SegFaultAXgoldfeld: That's what makes it both funny, and horribly depressing.
01:13SegFaultAXnoprompt: Science math and engineering is all there is.
01:13SegFaultAXDuh.
01:13SegFaultAXThere is nothing more to life.
01:13nopromptdesign != art and the younger generate is growing up missing out on that distinction.
01:13noprompt(inc SegFaultAX)
01:13lazybot⇒ 4
01:14noprompti spent my whole life doing (weird) art. no one gives a shit an no one wants to.
01:14goldfeldby the way where's the Civilization of our day?
01:14goldfeldi mean it's about time a new Great Game turned out right
01:14goldfeldare all our specialists working on the next iphone hit?
01:15goldfelderhmm, or of my day
01:15goldfeldthough i think i was at least barely born back when the first one came out
01:15SegFaultAXgoldfeld: I'm glad someone got the civ reference. :)
01:15nopromptmy only hope is that technology will eventually lead humanity to forsake money.
01:16goldfeldand played the second back when i barely understood what all the things i was producing meant
01:16nopromptmoney's a bad idea.
01:16nopromptit misplaces the emphasis on humanity.
01:18goldfeldSegFaultAX: civ was my last hold out as a gamer, that ship has sailed long ago but i really want to get back to regular playing of at least the innovative indie games coming around
01:20goldfeldi fear technology will do a bit more than make us forsake money, it may well forsake opportunity
01:21goldfeldin that scenario we're still a very privileged bunch in being born to a world where we can still make ourselves by our own work
01:21noprompti don't think that will be a problem
01:22goldfeldif all work is better done by technology, AI and robots, then the only humans standing to profit are the ones who own those
01:22goldfeldprofit not necessarily in a monetary sense, but in being able to provide value
01:23noprompt"value" is a relative term
01:23noprompthumans want to manifest themselves in some form or another.
01:23noprompti believe that is "value" enough.
01:23nopromptwhen humans do not have this bad things happen.
01:24goldfeldbut those scale across the hordes of people inhabiting this planet by that time?
01:24goldfeldbut does it*
01:24nopromptwhen you can augment reality as you see and hear it why not?
01:25goldfeldi think i see where you're getting at
01:25goldfeldthat might work indeed, though the romantic in me thinks something is lost in distancing ourselves from the 'real'
01:26goldfeldbut then that's my culture from this time
01:26nopromptfrom what i can tell, man seeks control over reality. this is the primary motivation for all scientific and artistic ventures.
01:26nopromptat least as i see it in my ignorant way.
01:26nopromptbut what is "real"?
01:26nopromptwhen you dream is that not "real"?
01:27nopromptall experience is real.
01:27goldfeldwell some of it is not persistent enough to be real, but i see your point
01:27goldfelda dream is not as real because it's so unstable
01:27nopromptso it's not real because you experience it?
01:28nopromptexperience must be real.
01:28noprompttherefore dreams must be real because they exist within the context of consciousness.
01:29goldfeldi can see there being alternative worlds sharing physical state with this one in the future, which is what i take your augmented suggestion to mean
01:29nopromptas far as anyone can tell what the do not experience is *not* real.
01:29noprompts/the/they
01:29goldfeldwherein new opportunity exists
01:29nopromptam i making sense here?
01:29noprompthad a couple glasses of cognac. :)
01:30goldfeldyou are, though i don't entirely agree that experience equates reality
01:30goldfeldoh that's fine, i had something else
01:30nopromptcounterpoint?
01:31goldfeldwell, if i'm sure that i'm living in the real world (or physical world)
01:32goldfeldand i leave a room, close the door, and open it again to find the room has become something else, i'd question it's reality
01:32goldfeldi have experienced the room while i was there, yet i question how real it is
01:34goldfeldsure, i don't necessarily question how real it was while i was there, but i question how real the context in which my experience took place really was
01:34nopromptso you don't equate sensation/experience w/ reality?
01:35goldfeldi have some attachment to the physical world, i'd say
01:35nopromptiow reality and sensation/experience are disjunct in your opinion?
01:36goldfeldwell yes, i think experience is a part of it
01:37goldfeldi think there's a reality that's independent of me and my experience
01:41dissipateis this ##philosophy or #clojure?
01:42danoyoungI have a stupid question, just leaning cascalog/clojure…and I see some code like this: #'string->local-date-time can someone explain the -> is the #'string referring to something like (var string)?
01:42nopromptdissipate: that is indeed the question. :P
01:42danoyoungthe whole line is: ((c/comp #'local-date-time->day #'string->local-date-time) ?txn-date :> ?day)
01:43dissipatenoprompt, is it true that Clojure is based on philosophy and notions of time and reality?
01:43goldfelddissipate: that's deep
01:43seancorfielddanoyoung: #' is a variable reference
01:44seancorfieldnormally you only use it as a short hand for (var ..)
01:44seancorfieldso #'local-date-time->day and (var local-date-time->day) are the same...
01:44danoyoungok…so what is #'string->local-date-time? I'm curios about the ->
01:44nopromptdissipate: imho, programming languages are more or less in some what the manifestation of some philosophy.
01:44dissipategoldfeld, think about the notion of immutability
01:44danoyoungok
01:44noprompts/in/are
01:44seancorfield-> is just part of the variable name
01:45danoyounggot it....
01:45dissipatenoprompt, what is the philosophy of Von Neumann languages?
01:45danoyoungthanx
01:45nopromptdissipate: not sure.
01:45seancorfielddanoyoung: foo->bar is a Clojure convention for a function that turns a foo into a bar
01:45danoyoungahh..thanx
01:46seancorfieldthe other time you'll see #'var-name is when pulling a private variable out of a namespace
01:46nopromptdissipate: but i'm sure there's something behind it. even mathematics and logic, and by extension computer science, are children of philosophy.
01:46seancorfieldsince there are no really private variables in Clojure
01:48danoyoungok…thanx for sharing...
01:48dissipateseancorfield, variables don't need privacy. BTW, isn't the 'proper' term symbol?
01:48seancorfieldyes, technically
01:49seancorfieldgroovy has the right idea: private is "advisory"
01:49nopromptseancorfield: what is your position on ^:private these days?
01:50seancorfieldI'll use ^:private on some implementation-specific data but I no longer write private functions
01:51dissipatenoprompt, if Clojure was a location on Earth, where would it be?
01:51seancorfieldright now about half our functions are private but i expect that to change
01:51seancorfieldClojure source 99 files 17235 total loc,
01:51seancorfield 1261 fns, 646 of which are private,
01:51seancorfield 199 vars, 7 macros, 29 atoms
01:52seancorfieldthat's our stats right now
01:52dissipatemy god, 646 private functions. that's ridiculous
01:53dissipatewhy do you need all that privacy?
01:53nopromptdissipate: it wouldn't be anywhere that i've ever been. certainly not a place on earth. i can't reference experientially a physical location i could connect with my state of mind while under the influence of clojure.
01:53seancorfieldlike i say, legacy code
01:53seancorfieldwe don't bother now
01:53amalloyyou still work on dating websites, right seancorfield? privacy should be important, see
01:53seancorfieldwe just haven't gotten around to making them all public... would make our test code cleaner :)
01:54seancorfieldamalloy: lol... members' privacy is important, our own functions not so much :)
01:54tolstoydon't the tests call the public functions, which call the private functions?
01:55seancorfieldtolstoy: well, that's the issue... we test some private functions... so either we shouldn't test them or they should be public
01:55dissipatenoprompt, did you know Clojure has a location on Earth? behold: http://what3words.com/*Clojure
01:55hiredmandissipate: it's everywhere you want to be
01:55dissipatehiredman, no, it's actually in Antarctica
01:55tolstoyseancorfield: I use private functions mainly just to keep the implementation details separate: but I guess a comment would work just as well.
01:56seancorfieldtolstoy: i'm leaning toward all public - you never know when those "implementation" functions will be useful to "client" code
01:57seancorfieldI haven't written a private function for a few months now... "I got better!" :)
01:57goldfeldseancorfield: do you think private functions are a bad thing?
01:57dissipateseancorfield, i haven't written a 'goto' statement in 3 days
01:57seancorfieldI think they're pointless... if they're pure functions they might as well be public
01:57goldfeldi tend to think of it as it being the kind of composing which has no real use in being exposed
01:58tolstoyseancorfield: Does the distinction between "app" code and "library" factor in to that?
01:58dissipategoldfeld, encapsulation comes from OOP. yuck
01:58goldfeldwouldn't it just confuse potential users if you exposed a bunch of building block functions which don't really work in the context of the api/dsl you want to offer?
01:59goldfelddissipate: i like to think in terms of bottom up design, not necessarily encapsulation
01:59goldfeldbut sometimes you don't want to take each layer of abstraction and put it into it's own library/namespace, so you just keep the real low level layers private
01:59amalloydissipate: i think it might not be in antarctica. i just searched for clojure on factual, and the one result is an italian restaurant in pittsburgh: http://www.factual.com/data/t/places#q=clojure
01:59goldfeldotherwise it's just confusing for users
02:00dissipategoldfeld, can't you pick which symbols get imported into the namespace by default?
02:00tolstoygoldfeld: that's kinda my take on it.
02:01hiredmangoldfeld: as a consumer of many libraries, it sucks when people who write libraries make it harder to use what I want from them
02:01goldfeldbottom up design and these building blocks are good because when you want to change or add features they might prove really helpful in code reusability
02:01hiredmanprivate is just silly
02:02dissipateamalloy, well, it's there now. http://what3words.com/*Clojure
02:02goldfeldhiredman: doesn't tha argument go both ways? i think there's a balance, you may expose too little or presume your user doesn't want to use it (which i take is your argument), but you can also expose too much and overwhelm the user, create friction and make it more confusing to use your lib
02:03hiredmangoldfeld: the correct thing to do if you care about users is to write docs
02:03seancorfieldtolstoy: no, I see no point in private functions anywhere now
02:03hiredmangoldfeld: marking things as private or not has no effect on my ability to read code
02:04seancorfielduse namespaces to separate API from implementation
02:04hiredmanI just mentally check the "this was written by one of *those* people" box in my head
02:04hiredmanand go on reading
02:04goldfeldhiredman: i agree that docs are the ideal case
02:04seancorfield++hiredman
02:04dissipateseancorfield, that's what i just said!
02:04dissipateseancorfield, why can't you just set the default imports?
02:05seancorfieldwe're all in violent agreement then :)
02:05tolstoyNow everytime I type defn- I know I'm sinking another level in hell.
02:05dissipateseancorfield, except for the location of Clojure
02:05goldfeldin among namespaces and docs i think i can agree with you guys as well
02:05hiredmangoldfeld: private isn't even a "less than ideal case" it is just being silly
02:05seancorfielddon't worry tolstoy I've written my fair share of defn- but that will change :)
02:06dissipatetolstoy, why is that?
02:06tolstoyseancorfield: I think the use/not-use of it is such a trivial issue that it's not even worth calling it "silly".
02:06goldfeldyou may have spurred a change within now
02:06goldfeldactually 'defn-' is pretty bad to start with
02:06tolstoydissipate: I was just being snarky about how foolish one can be made to feel using a language feature. ;)
02:06goldfeldi find it barely readable
02:07goldfeldespecially when quickly scanning code
02:07hiredmanclojurebot: private is <reply> not even once
02:07clojurebotOk.
02:07seancorfielddefn- only exists because it's hard to get rid of.. but there's no def- and clojure/core has repeatedly rejected calls for it
02:07tolstoyYep.
02:07goldfeldwithin me*
02:07tolstoyBut I likes it. ;)
02:07goldfeldyes, i have used only defn ^:private
02:08goldfeldout of spite
02:08tolstoyI also like a few ;;------------- mixed in there. ;)
02:08NyyxI cant discard arguments in lambda macros can I? (fn [_] (do-whatever)) -> #((do-whatever))?
02:08dissipatetolstoy, defn is not a builtin
02:09seancorfieldNyyx: not sure what you're asking there...?
02:09tolstoyI was refactoring someone else's all-public namespace, and couldn't tell which functions were used externally.
02:09Nyyxthe former takes an argument and does nothing with it
02:09Nyyxbut the latter doesn't take an argument
02:09Nyyxand I need it to, but throw it away
02:10goldfeldtolstoy: yes, i still think there might be use for the lone private function
02:10seancorfieldEr, so why use #(..) instead of (fn [_] ..) then?
02:10NyyxI know I can do it with a higher order function but that's not what I want
02:10Nyyxlazy to type fn [.. ]
02:10Nyyx>.>
02:10tolstoydissipate: You mean it's a macro built out of primitives?
02:11goldfeldi mean, what do you do, pull it out into a separate namespace just for that one function? even if you have great docs, if the function is of no use externally it seems out of place for it to be public
02:11seancorfieldNyyx: that makes no sense :) use the correct construct!
02:12dissipatetolstoy, that's correct. i believe 'def' is a builtin but not 'defn'
02:12seancorfieldgoldfeld: no use to who? the user of the library may well find it very useful
02:13dissipatetolstoy, but its not a macro. the builtins are not macros. they are just part of the language, the core constructs.
02:13tolstoydissipate: Yeah. Clojure's the first language I've used where, when I didn't understand the doc string (or it seemed ambiguous), I could hit the "source" link and actually expect to have my question answered.
02:13goldfeldseancorfild: but wouldn't that be incidental? you might as well say he might find a completely unrelated (to the problem the library solves) function thrown in might just be useful for a given user
02:13goldfeldacidental*
02:13seancorfield(defn f [..] ..) is just (def f (fn [..] ..))
02:13tolstoyDoesn't defn also add metadata where def doesn't, or something?
02:13seancorfieldhiredman: help me out here :)
02:14tolstoyLike defn also has metadata about the argument list or something?
02:14seancorfieldtolstoy: sure, yes, but that's not a big deal - i was just simplifying
02:14hiredmangoldfeld: the end user is in far better place to decided is useful than you are
02:14seancorfield,(source defn)
02:14clojurebotSource not found\n
02:14seancorfieldbah!
02:14dissipatetolstoy, oh sorry, i meant defn is a macro, but builtins are not macros.
02:14tolstoyseancorfield: Yep. ;)
02:14goldfeldseancorfield: what i'm saying is there's this domain, this dsl which the library models, and it's less of a cognitive load to 99% of the users to provide it cleanly
02:15tolstoydissipate: Yep, I get what you're saying.
02:15seancorfieldgoldfeld: right so use two namespaces - the DSL and the implemntation - if it's important to keep them separate
02:15hiredmanyou are hiding laziless (not wanting to deal with the friction of a new namespace) behind supposed concern over users cognitive load
02:16hiredmanhow do you measure that cognitive load? have you done studies showing it was a problem?
02:16seancorfields/laziless/laziness/ i assume?
02:16hiredmanyes
02:16goldfeldi
02:16goldfeldmy bigger concern is not my lazyness
02:16hiredmanusers are not babies to be coddled
02:16goldfeldit's the users' lazyness
02:17hiredmannor do they need to be
02:17seancorfieldgroovy takes the position of "who are you protecting things from?" and i (now) agree
02:17seancorfieldclojure allows you to circumvent privacy with #'
02:18seancorfieldprivacy is an illusion
02:18goldfeldhiredman: i know what you're saying, but i'm not sure i agree you should treat every library user as a power user who'll read the fucking manual, especially in the context of wanting the most people to use your library
02:18tolstoyWhich doesn't mean it's not a useful one.... (but I'm not a library writer).
02:19hiredmanprivate is from conceit of being a grand architect of software, instead of acknowledging the wrapper library you are releasing will save a some guy at a start up and afternoon, and then he'll have to rip it out in 2 months anyway, because the assumptions in it don't match his use
02:19goldfeldlet's call it open source marketing
02:19Nyyxseancorfield: I'm from haskell I'm lazy by default
02:19hiredmanan
02:19dissipatehiredman, ever heard of Programmer Anarchy?
02:19hiredmandissipate: yes
02:20dissipatehiredman, under Programmer Anarchy everything gets ripped out all the time. :P 2 months is a dog's age for an app.
02:20seancorfieldhiredman: I (now) agree that private is a ridiculous conceit from OOP that makes no real sense in real world programming
02:20hiredmanseancorfield: welcome to the foldl
02:20seancorfieldNyyx: sorry about Haskell :)
02:20goldfeldi do agree separate namespaces for different levels of the dsl is the better solution
02:21hiredman~rimshot
02:21clojurebotBadum, *tish*
02:21seancorfieldfoldl or foldr? :)
02:21goldfeldbut i'd still take private fns over a dump of public functions all on the same namespace and no api docs
02:21seancorfieldAPI docs = docstrings
02:22seancorfieldthere's no separation
02:22goldfeldwait, wait
02:22goldfeldbut then how do you provide an easy referenc index of what's the 'dsl'?
02:22goldfeldi mean, if you don't have separate namespaces for different levels
02:22tolstoygoldfeld: And when you're writing an app, it seems overkill to create deeper levels to put implementation details. Balance and proportion!
02:23goldfeldi think there's docstrings and then there's 'general usage' summary
02:23goldfeldtwo parts of the documentation
02:24seancorfieldgoldfeld: I didn't say I supported a single namepsace for the whole library
02:24goldfeldthe usage part points towards what the idea of the dsl is
02:24seancorfieldyou can have docstring on ns too...
02:24dissipatetolstoy, your app shouldn't be more than 200 LOC
02:25goldfeldseancorfield: i agree that's the way to go
02:25hiredmanor, you know, a readme
02:26goldfeldin any case i'm now discussing just hypothetical non-best-case scenarios of library design, so i guess it's time i stop
02:26hiredmanI always just end up reading the code anyway
02:27seancorfieldweirdly I converted java.jdbc from two namespaces to one, based on feedback from Clojure/core but I think that feedback would be different these days
02:27dissipatehiredman, what do you think of writing apps that were just tiny services that you string together? it's the Unix way.
02:28goldfeldyou guys did convince me to start just putting my private functions in 'lower level' namespaces, making them public
02:28goldfeldso thank you
02:29hiredmandissipate: *shrug* osx is the only widely used unix microkernel I am aware of
02:29goldfeldsuddenly the defn- vs defn ^:private in my head's been made irrelevant
02:29seancorfieldI would say "public by default" unless you have a really good reason to make something private - and remember it can still be acceessed anyway
02:33goldfeldi think you actually won me over when you started attacking OOP
02:34maxthoursiewait, is there a difference between defn- and ^:private ?
02:34maxthoursiedosen't read that way to me: (list* `defn (with-meta name (assoc (meta name) :private true)) decls)
02:35seancorfieldmaxthoursie: er... did someone say they were different?
02:36seancorfieldgoldfeld: oh let me attack OOP some more :)
02:36maxthoursiemaybe not, I got the impression by goldfeld prev comment
02:37goldfeldmaxthoursie: the vs. was entirely around style and readability
02:37seancorfieldI started out with FP and learned OOP later to stay employed... and now FP is coming back to the mainstream... heck I spent 8 years on the C++ committee! :)
02:37maxthoursiegoldfeld: ah, ok, false alarm then :)
02:37seancorfield(defn ^:private...) and (def ^:private...) are more consistent... (defn- ...) is the odd one out...
02:38goldfeldseancorfield: so what were your FP beginnings?
02:38seancorfieldSASL and Miranda - and a PhD in functional language design and implementation :)
02:39goldfeldit's funny back when i got into engineering they taught me Fortran, meanwhile compsci taught Haskell and everyone found that somehow weirder than mine
02:39maxthoursiecool, that's two languages I hadn't heard about
02:40goldfeldthat was around 8 ago
02:40goldfeldyears*
02:40seancorfieldI learned assembler first TBH... then BASIC and Pascal... and Lisp... and I learned FORTRAN and pl/p and COBOL and a bunch of other languages...
02:40goldfeldseancorfield: way ahead of the curve
02:41seancorfieldfor my PhD I developed my own language - SURE - on top of Peter Henderson's LispKit
02:41goldfeldmaxthoursie: for a moment i thought you were talking about the languages i mentioned
02:42seancorfieldmy final year project at university was to write an APL interpreter
02:42maxthoursie:)
02:43goldfeldi sometimes think if had been born around that time i would be pretty happy if had gotten into lisp and emacs and all that, i mean we have all this web stuff and they were doing some pretty advanced and interactive stuff back then and the workflow you could achieve were tighter and more consistent and customizable in a good way than mostly all that are popular today
02:43goldfeldugh, missed some I's
02:43seancorfieldI went back to Emacs in September 2011 after about a 20 year gap...
02:44seancorfieldI started with Emacs 17.x and shifted away from it as 19.x came out... and went back at the tail end of 23.x... but now I'm a LightTable guy :)
02:45goldfeldtoo cool
02:45goldfeldi have stolen many a trick LightTable uses for node+cljs as well node-webkit
02:45goldfelddoing a pet project on top of it with cljs as well
02:46goldfeldso the open sourcing was a real boon for me
02:46amalloyemacs 17.x! i didn't know there were any versions before 22
02:47amalloy(wouldn't that be great? the next project i release will go straight to version 19)
02:47goldfeldif you consider how long it's been around, you could say they were relatively conservative with major release numbers
02:49tolstoyAren't the version numbers really 0.22, 0.23? When did they give up the leading 0?
02:49seancorfieldemacs 15.34 appeared in 1985
02:49dissipateseancorfield, why do so many sneer at light table, or don't consider it a 'real' IDE?
02:50seancorfieldno idea... i switched over from emacs when 0.6.0 appeared and use it full-time every day for all my editing
02:51rurumateI have an atom (def init-done? (atom false)) and a function (defn init[] (when-not @init-done? (reset! init-done? true) (println "Init: done"))) that must be guaranteed to run only if init-done? is false, and at most once then. Needs (synchronized) or something? Thanks
02:51goldfeldthe only reason i don't switch for my clojure editing is evil-mode
02:51dissipateseancorfield, wow, interesting...
02:51goldfeldthough maybe if i really learn paredit i could do without evil
02:52goldfeldand lt's vim mode might be sufficient
02:52seancorfieldok, bedtime here... chat tomorrow
02:52goldfeldis LightTable even supposed to be a 'real IDE'? isn't more of an editor on steroids?
02:53goldfeldi guess i oughta be going too
02:53rurumateor maybe locking
02:53dissipateseancorfield, what do you think of Forward Inc.'s claim that they don't write apps more than a few hundred LOC?
02:53systemfaultgoldfeld: I think it was "marketed" as an IDE.
02:54rurumatethe interesting thing is that there is no "see also" here: http://clojuredocs.org/clojure_core/clojure.core/locking
02:54systemfaultgoldfeld: https://www.kickstarter.com/projects/ibdknox/light-table?ref=live "Light Table is a new kind of IDE - a reactive work surface for the creation and exploration of our programs."
02:55dissipatesystemfault, but has it lived up to the hype?
02:59rurumatetalking of emacs, emacs' clojure mode syntax highlighter apparently doesn't highlight 'ignore next form' comment block a la #_(won't-run) property
02:59rurumate*properly
03:01dissipaterurumate, how well does emacs highlight heredocs?
03:02rurumateI dunno, not at all? Is theere
03:02rurumate*is there a reason?
03:04rurumateor should I rather ask these things in #emacs
03:05dissipaterurumate, just curious. a lot of editors do not highlight them properly
03:05rurumatethere's another thing that bugs me in the emacs cider repl, it's that sometimes emacs prints a bunch of newlines before the return value when hitting <RET>
04:15ericdwhiteI'm looking for an idiomatic of validating inputs in clojure. Does anyone have some examples/
04:15ericdwhite'idiomatic way of ...'
04:17clgvericdwhite: you mean parameters passed to functions?
04:18ericdwhiteyes, I have data coming in from a JSON API in a map and I want to do some validations before passing that on
04:19ericdwhiteclgv: I was doing it inside of let [] deconstructions but it felt wrong
04:22clgvericdwhite: you can specify :pre :post validations for every function with pure clojure. if that is not enough you can have a look at clojure.core.contracts lib
04:22clgvericdwhite: for checking the content schema of maps there are several libs
04:27ericdwhiteclgv: I just found this post where they use core.match : https://groups.google.com/forum/#!topic/clojure/9W_4COx5Bhc
04:32clgvericdwhite: well, core.match is for advanced branching logic and not really intended for parameter validations
04:34ericdwhite:clvv: yes, but I thought the approach of switching based on a validation returning a map of errors was good
04:35ericdwhiteclgv: (match (validate my-map) and then [{:errors errors} original-map] (handle-errors) or [_ original-map] (save original-map)))
04:38clgvericdwhite: I would not try to pull in every clojure library there is, if I were you ;)
04:39clgvericdwhite: if you really get benefits from core.match go for it but the sample above suggests that pure clojure with destructuring suffices
04:45ericdwhiteclgv: Thanks. I need to put together a real example, as I'm new to clojure, to critique. And to your point I don't want to pull in every library there is.
05:03riz_hi
05:03riz_I'm confused about an atom statement
05:03riz_would anybody be willing to explain?
05:25noto2riz_, sure
05:25riz_thanks here's the line:
05:26TEttingerif it's over a line or two use a pastebin
05:26riz_(def app-state (atom {:testimonials (shuffle testimonials)}))
05:26riz_what exactly is this doing?
05:27riz_here's the link:
05:27riz_http://danielsz.github.io/2014/02/28/The-pleasantness-of-Om/
05:27riz_It says the testimonials are stored in a Vector of maps
05:28TEttingerit's defining app-state as an atom (a way of handling state). the atom contains a map with the key :testimonials, its value is a randomly-ordered vector of maps drawn from what you just said
05:29riz_ok makes sense
05:29riz_what about the next line:
05:30riz_(defn transition [state] (om/transact! state :testimonials #(if (seq (pop %)) (pop %) (shuffle testimonials))))
05:30TEttingergotta say I haven't used Om and am not familiar with its API
05:31TEttingerI'm guessing that's something like swap! in normal clojure.core
05:32riz_so it basically pops the value out of a sequence, otherwise pops the last value and shuffles the testimonials again and assigns it to :testimonials ?
05:33TEttinger(doc pop)
05:33clojurebot"([coll]); For a list or queue, returns a new list/queue without the first item, for a vector, returns a new vector without the last item. If the collection is empty, throws an exception. Note - not the same as next/butlast."
05:34riz_so if seq would fail if there were no items left?
05:34TEttingeryes
05:34TEttingerif there's one element
05:34riz_oh ok
05:35riz_so it seems it's doing pop % whether it's seq or not
05:35TEttingerand it pops it, (seq (pop [1337])) will return nil
05:35TEttingerpop isn't mutating the list though
05:36TEttingerand that's an if block
05:36TEttinger(if (seq (pop %)) (pop %) (shuffle testimonials))
05:37TEttingerthat says, if there would be at least an element left after popping from the arg %, then return (pop %), else return (shuffle testimonials)
05:38riz_ohhhhh
05:39riz_that makes perfect sense :)
05:39TEttingerhooray!
05:39riz_yeah i for some reason was thinking it was modifying the sequence - how imperative of me!
05:40riz_thanks very much for explaining :)
05:40TEttingerno problem :)
05:40riz_btw, do you know about the google summer of code?
05:40TEttingersorta yes
05:41TEttingersummer seems a ways off still
05:42riz_the applications start in march though
05:42riz_do you use Light Table?
05:43TEttingeryes, sometimes. also nightcode
05:43riz_do you write clojure for a living ?
05:44TEttingernope, hobbyist
05:44riz_I'm wondering what sort of tools people use for large scale clojure development
05:44riz_in order to debug, test, etc
05:44TEttingerprismatic is doing it, not sure how
05:44TEttingerbut they're definitely large-scale clojure
05:46riz_oh never heard of their app
05:46TEttingertheir libs are used more I think haha
05:46TEttingerbut they are quality libs
05:46riz_oh are they open source?
05:46TEttingersome
05:46TEttingerhttps://github.com/Prismatic/hiphip is one
05:47riz_what do you like about nightcode?
05:47TEttingerhttps://github.com/Prismatic/dommy also gets a lot of attention
05:48TEttingeruh, it seems a bit more working than light table's instarepl. I could never get that to work, and night code just has a whole repl pane (2 actually for experiments)
05:50TEttingerI better get some rest. good luck with the Om stuff!
05:50riz_thanks :)
05:50riz_i'll try out night code
05:54lnostdalhi guys, does using declare for forward declarations of functions (defn) mean the resulting call site(s) will go via some indirection? ..or perhaps the indirection is always there; perhaps until the JIT figures out whats going on in any case(?)
05:57clgvlnostdal: the indirection is always there for normal clojure functions
05:57lnostdalclgv: ok, thanks!
05:57clgvlnostdal: otherwise you could not redefine functions and use them immediately without recompiling all the other dependent namespaces
05:58lnostdalyep
05:58clgvafair that indirection could be improved by invoke dynamic of java 7
06:34jaleycan anyone point me at a guide to making java 7 work on mavericks? i've been googling around and just can't make my oracle java 7 install available to all apps
06:38spelufoIs it in your PATH?
06:39spelufodo `echo $PATH` on the command line. I am on Ubuntu 12.04 and I have it in /usr/lib/jvm/java-7-oracle/bin
06:41spelufoactually, I have all the following in my path: /usr/lib/jvm/java-7-oracle/bin:/usr/lib/jvm/java-7-oracle/db/bin:/usr/lib/jvm/java-7-oracle/jre/bin:/home/santiago/bin:/usr/lib/jvm/jdk1.7.0/bin
06:43hyPiRion`sudo update-alternatives --config java` ?
06:46dsrxd'oh.. just learned C-c C-c does the same thing as C-M-x (and is way easier to type)
07:10clgv(inc clojure.test.check)
07:10lazybot⇒ 1
07:24jaleyre: java setup, for reference - I actually found the Java subheading in this page worked: http://derjan.io/blog/2013/11/25/setup-mac-for-development/ (I had the JRE installed, but not the JDK linked from there)
07:45john2xping bitemyapp
07:53random123Could someone suggest a website where I could learn closure like learnstreet etc
08:10clgvIs it possible to manually add line metadata to the code generated in a macro?
08:11clgvsuch that I'll get it displayed on an exception?
08:40BalkyDwarfrandom123: 4clojure.org
08:44kathyHola!
08:45PupenoHola kathy, como estas?
08:45kathyHola, bien y tu?
08:45PupenoBien bien, gracias.
08:45kathyMe alegra!
08:46Pupenobbl
08:47kathyQue?
08:47kathyHolaaa
08:48Pupenokathy: en un rato vengo.
08:49kathyOk!
09:02john2xhi. i'm new to using the emacs+cider environment. I've already jacked-in, but I've added a new dependency to my project.clj. How do I load this new dependency without closing my repl session?
09:03carkas far as i know, you need to restart it
09:22gfredericksjohn2x: yeah in general (regardless of cider) you have to restart after changing deps
09:22clgvis there a macroexpansion function where you can specify which macros should be expanded and the remaining ones are untouched?
09:23ericdwhiteOk, I'm back with an example about validating some JSON input that I have read into a map. This code is for critique, as I don't think this is the best approach for validating input
09:23john2xcark, gfredericks: thanks. coming from vim, it's not so bad with cider. feels like nothing at all.
09:23ericdwhiteI have put the sample code here: https://www.refheap.com/49553
09:23gfredericksclgv: I've thought that would be nice a lot of times
09:23clgvgfredericks: yeah. but damn that means you dont know one
09:24john2xyeah that would be useful
09:24gfredericksericdwhite: oh no oh no this is the either monad
09:25gfredericksevery time you end up writing monad code in not-haskell, an angel loses its wings
09:25clgvhaha
09:25gfredericksclgv: you'd want it to work recursively like with macroexpand-all?
09:25clgvgfredericks: I thought of patching mexpand-all from tools.macro
09:26gfredericksclgv: I was about to mention tools.macro
09:26gfredericksclgv: I think the most general API would be supplying a predicate that takes a var or symbol and decides whether or not to expand it
09:26clgvoh wait there is something like "protected-symbols" in tools.macro
09:27gfredericksyeah?
09:27clgvnot sure what it does exactly just tracing it through the code
09:27gfredericksericdwhite: lines 15->17 could be cleaned up with ->>
09:28gfredericksericdwhite: and lines 3-4 and 8-9 could use cond->
09:29ericdwhitegfredericks: thanks let me give it another pass
09:29gfredericksericdwhite: but the whole thing could be a bit more declarative
09:30gfredericksto factor out the common parts you'll get between all validators
09:31gfredericks(defn make-validator [pred err-key msg] (fn [input errors] (cond-> errors (not (pred data)) (assoc err-key msg))))
09:31gfredericks^ for example
09:32ericdwhiteok let me try that
09:32gfrederickss/data/input/
09:34clgvgfredericks: monkeypatching tools.macro and using the protected symbol map does not seem to work :(
09:36gfrederickshuh; it's dynamic, but private
09:36gfredericksveird
09:36gfredericksweird
09:37gfredericksoh the comment on line 44 suggests it's for locals
09:38gfredericksI wonder if it's only for symbol-macros?
09:39gfrederickslooks like it should work as best I can tell
09:42clgvgfredericks: ah it works. I forgot to add both symbol and resolved symbol
09:57clgvharr errors are much easier to spot when a "when" is a "when" instead of expanded to an "if"
10:01clgvI remember that there was a clojure editor component announced as library on the mailing list. how was it called?
10:12ericdwhitegfredericks: Do you mind have another look at: ttps://www.refheap.com/49563
10:13ericdwhites/have/having/
11:01clgvericdwhite: but as I said, there are libraries for this task, clj-schema, prismatic/schema ...
11:03ericdwhiteclgv: thanks, I'm just trying to get my basic clojure to a decent level. I will take a look at those libraries.
11:04ericdwhitefor example is it a good idea to use -> the way I did inside the let statement, or is that a totally bad idea.
11:14benmossdoes anyone know if there's a way to use Schema with multi methods?
11:15benmossi mean aside from just calling validate, there's no macro for defining the defmethod and the schema for the arguments
11:17tgoossensI've not been following clojure news for 3 months. What did I miss ? :)
11:18seangrovebenmoss: That's a good question, I hadn't looked into that at all
11:18gtrakwrap the multimethod in another defn.
11:19gtrakbut I feel to lazy to do that for protocols, too
11:19benmossgtrak: like triple dispatch?
11:19gtraktoo*
11:19gtrakyea
11:19benmossyeah, that could work
11:19gtrakanother level of indirection solves everything
11:19seangroveOr actually, in th defmulti, have a {:pre } check in your method you're using to dispatch
11:19seangroveThat's essentially what gtrak suggests, just without an extra fn
11:20benmossthats a good idea, i forgot that was a possibility
11:28seangroveI think this weekend I need to write some posts about Omchaya and the design decisions
11:28seangroveThis "auto-reload state" thing is amazing
11:29`cbpomchaya?
11:29`cbpoh i see
11:30bbloomseangrove: what's the auto-reload state thing?
11:30seangrovebbloom: https://www.dropbox.com/s/vdnjnmfb5b120gk/om_save_restore.mov
11:31seangroveHit ctrl-s, the state is serialized and written to localStorage. Reload it by hitting ctrl-r, or have it auto-reload if you add ?reload-state=true to the url
11:31bbloomwhich is really the past
11:31bbloomthat is super nice
11:31bbloomgood job
11:32seangrovebbloom: ~4 lines of code
11:32seangroveWhen your world is serializable, everything is easier
11:32bbloomseangrove: true story.
11:33seangrovebbloom: It's such a tiny change, but I'd like ot think of a way to make it a component someone could just drop it
11:33seangroveBeyond just good patterns people can learn from, I'd really like to get to actualy reuse/sharing
11:34bbloomseangrove: can't you get access to the entire data subtree (violating encapsulation) of all sub components?
11:34bbloomseangrove: ie couldn't you just have a component which wraps the root?
11:35bbloomwould be cool to just have a heavily parameterized root component for debugging tools
11:35seangrovebbloom: That's a good idea
11:35seangroveSo, I have the blog posts writing about this stuff, histor replaying, metrics, overall design, and I need to come up with the StackPanel component :)
11:35bbloomif you wanted them, all you need to do is change your app from <MyRoot.../> to <RootWrapper saveload={{true}}><MyRoot...
11:36bbloomwould be awesome if that root wrapper had like a floating toolbar too, so you could configure it
11:37bbloomturn on/off various things, stores all it's config in local storage, lets you save/load/merge it's config for sharing with the team, etc
11:37seangrovebbloom: Yeah, that's what I'm wondering. With the history player, state inspector, saving state to different slots, how do you get it to look/act coherently while still being composable
11:37bbloomlike having a replay slider, state inspecter, etc
11:37bbloomyeah
11:37seangroveIt's actually probably not too bad
11:38seangroveA tab component, draggable window component, and then let people put in the components they want for their debug toolbar
11:38bbloomthe naive thing probably works: have them bubble events up to the root debugging component
11:38bbloomdon't let them write to storage locally, just have them bubble save/load requests
11:38bbloomthen the root component can prefix their state keys to isolate them, etc
11:39seangrovebbloom: https://github.com/sgrove/omchaya/blob/master/src/omchaya/controllers/controls.cljs#L200 and https://github.com/sgrove/omchaya/blob/master/src/omchaya/controllers/post_controls.cljs#L148
11:39bbloomi wouldn't go too nuts w/ customizing the toolbar yet. i'd just start w/ the ugliest arrangement of shit you can cram in to a floating or fixed panel & see what makes sense from there
11:39seangroveI really like the multimethod with controller/post-controller approach
11:39bbloomseangrove: heh, is this exactly what i suggested around bubblign control events?
11:39seangrovePretty much ;)
11:39seangroveThat's how we designed our app, and then how we built Omchaya
11:40bbloomperfect.
11:40bbloomreally nice work
11:40bbloombrb
11:40seangroveTake a look at it when you get a chance, would love to hear if you have other suggestions around it befor eI write too much
11:55seangrove,(let [x (atom {:a 10 :b [20 30]})] [(identical? x (swap! x identity)) (identical @x @(swap! x identity))])
11:55clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: identical in this context, compiling:(NO_SOURCE_PATH:0:0)>
11:55seangrove,(let [x (atom {:a 10 :b [20 30]})] [(identical? x (swap! x identity)) (identical? @x @(swap! x identity))])
11:55clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.util.concurrent.Future>
11:56seangrove,(let [x (atom {:a 10 :b [20 30]})] [(identical? x (swap! x identity)) (identical? @x (swap! x identity))])
11:56clojurebot[false true]
11:56seangrove,(let [x (atom {:a 10 :b [20 30]})] [(= x (swap! x identity)) (= @x (swap! x identity))])
11:56clojurebot[false true]
11:56seangroveIdentity and equality are hard.
12:00amalloyseangrove: i don't see what you're trying to demonstrate (or confused about?)
12:00seangroveamalloy: Oh, not demonstrating anything, sorry. Just checking some assumptions
12:01seangroveThe first check is obviously wrong looking at it now, please disregard ;)
12:05tgoossensborkdude, lang geleden :)
12:05tgoossens*long time no see
12:06borkdudeIs there a lib which expose reference types with history as in Datomic? Like (get! some-atom #inst 'an hour ago') ?
12:06borkdude(deref ... #'inst 'an hour ago')
12:07borkdudetgoossens hi
12:07borkdudetgoossens I have been here regularly ;)
12:07tgoossensi know
12:07tgoossensIt's me who has been inactive for a few months in the clojure community
12:07borkdudetgoossens actually me 2, but since a few weeks it's getting more active
12:08tgoossensNew project? Or courses that are starting?
12:08borkdudetgoossens I'm not a lecturer anymore, but I have been doing a clojure project, then Java, and then clojure again
12:08tgoossensoh
12:09tgoossensMy excuse is that my masters study already demands a lot of programming work. Mostly numerical (with matlab, fortran) that usually I don't have the urge and will to do even more programming with clojure :p
12:09borkdudetgoossens I know the feeling, Java drains all your positive energy ;)
12:10tgoossenshha
12:11tgoossensI should put some more time into my clojure meetup. I'm getting a bit sloppy
12:17tgoossensborkdude, did I miss some shocking news in the clojure world?
12:20borkdudetgoossens Datomic Pro has a free to use variant
12:20borkdudetgoossens There is a new front end library which I hear a lot about called Om
12:21borkdudetgoossens Maybe Cursive Clojure?
12:21borkdudetgoossens Caribou
12:21borkdudetgoossens Version 1.6 coming soon
12:21borkdudetgoossens I don't know for the rest
12:22borkdudetgoossens Schema and Liberator, but those aren't really new
12:22tgoossenshmm a clojure IDE
12:23borkdudetgoossens Hoplon is also coo
12:23borkdudel
12:23tgoossens:D
12:28tgoossensis there already a talk on cursive available somewhere?
12:52lockserr’body talking about Om :}
13:00seangroveLiking our hn job postings more and more each month. Think we're building up a reasonable profile for good engineers.
13:06wei__getting a bit confused with Om. I'm just trying to bind a set of text boxes to keys in the global app-state atom. is there a similar example somewhere?
13:06seangrovewei__: text inputs?
13:07wei__yeah, so I have three text inputs. they should all update (according to a formula) when you change any of the inputs
13:07seangrovewei__: It's slightly tricky, but not horribly so. Can you paste your component and atom code somewhere?
13:08wei__sure thing, thx. give me a sec..
13:09bjorkintosh366 in #lisp but 681 in #clojure. where did CL fall short?
13:09bjorkintoshmuch amaze. very wow.
13:12RickInAtlantabjorkintosh: how do you search by language?
13:12AimHereProbably just asks his client for a list of how many people are in each channel
13:12bjorkintoshtop right in xchat, RickInAtlanta.
13:13RickInAtlantathanks
13:14isaacbwcommon lisp isn't 'in' anymore
13:15bjorkintoshnaturally :)
13:15wei__seangrove: https://gist.github.com/yayitswei/9294380 .. probably horribly un-idiomatic :)
13:15wei__it also doesn't quite work yet
13:16pepijnHow do I make a list of distinct elements in core.logic? Like (fresh [a b c d ....] (fd/distinct a b c d....))
13:16seangrovewei__: Hrm, I don't use render-state, I'd have to look up what that's for
13:16seangroveHow's it different from just om/IRender?
13:17wei__it takes a local component state
13:17wei__which I actually don't need here, hmm
13:18seangrovewei__: I don't think changing opts will trigger a re-render
13:19wei__shouldn't (swap! app-state ...) trigger a re-render?
13:19seangrovewei__: One second, let me see if I can refactor this a bit
13:23wei__also I don't understand why the text fields aren't populated with the initial values in app-state-- so it's not getting linked correctly
13:25seangrovewei__: is the label rendered correctly?
13:25qbgWhy does numeric-input have :value (id state)?
13:25wei__yes, the label shows up
13:25qbgShouldn't that be (id input)?
13:26qbgAlso, if you're going to use IRenderState, you should either specify the initial state when using om/build, or also extend IInitState
13:27wei__qbg: my intention is to have the text box linked to a value in app-state. so text box A's value should be (get-in @app-state [:options :a]), and so on
13:28seangrovewei__: https://www.refheap.com/542dc1f51bf05110b74cef51f
13:28seangrove(id state) seems wrong first off
13:28seangroveshould probably be (get-in state [:options id]), I think
13:28qbgI don't see any reason for local state here
13:28qbgyou want to be using input
13:29wei__even if I used :path at the bottom to base the cursor off :options?
13:29qbgAnd handle-numeric-change shouldn't be touching app-state directly
13:29qbginput is a cursor
13:30qbg(id state) should be (id input)
13:30seangrovewei__: I think you might be right about :path, good point. Happy to hop on a google hangouts to pair. Probably faster
13:31qbgand handle-numeric-change should be taking in input and using om/transact!
13:31wei__qbg: (id input) does give me the correct initial display
13:32wei__what's the difference between om/transact! and (swap! app-state ..) ?
13:32qbg(swap! app-state assoc-in [:options id] (text->value text)) should most likely be (om/update! input id (text->value text))
13:32qbgom/transact! operates on a cursor
13:33qbgand affects what is pointed to by the cursor instead of the whole state
13:33wei__will swap! trigger a re-render though?
13:33qbgit should
13:34wei__seangrove: let me puzzle it out a bit more, will definitely hit you up if I get stuck- really appreciate it
13:35seangrovewei__: Definitely. And also check out Omchaya, it's a good reference point.
13:36seangrovebbloom: That reminds me, the previous links weren't entirely fair. A few lines here to pass the messages to the controller https://github.com/sgrove/omchaya/blob/master/src/omchaya/components/app.cljs#L40
13:43eraserhdWhat is the go-to in-process backed-by-a-file database for clojure? The thing that's SQLite in everything else modern and DBFs in the olden days?
13:45`cbpum
13:45`cbpwell i use h2 from time to time
13:49plooknwhat's wrong with sqlite?
13:53pepijnwhat the... is this? (core.logic): (( 0 :- (!= ( 1 2))))
13:55iwohey, can anyone help me with a link to the clojure blog where the author makes all their posts as code?
13:55iwoi can't remember his name, but the blog posts are usually just a lot of code showing a worked example, and all the descriptive text is in comments in the code
13:56bbloomseangrove: i wasn't looking too closely anyway :-P
13:57seangrovebbloom: Well, just a nice architecutre
13:57pepijnCondensed code: https://www.refheap.com/49699
13:58pepijnI just try to create couples of players. If I say (player q) that gives the expected result, but calling couple gives unground but constrained lvars, if I'm not mistaken.
13:59iwosome of his posts are very popular, his blog is something simple like blogspot, he has a photo of himself in the sidebar and iirc he's balding
14:00pepijnThe result actually is ((_0 :- (!= (_1 _2))))
14:04pepijnnvm, I remembered something stupid
14:15kathy1Hola
14:17wei__seangrove: qbg: updated the om app with your suggestions and it's mostly working now. https://gist.github.com/yayitswei/9294380 one issue: inc seems to append a 1 to the end of the textfield instead of add one, do you know why?
14:18seangrovewei__: Probably it's operating on a string
14:18seangrovejavascript "9" + 1 => "91"
14:18gfredericksgtrak: ping
14:19wei__it should operate on the result of #(if empty? % 0 (js/parseFloat text))), which I expect to always be numeric
14:20eraserhdplookn: I'm not saying anything's wrong with it. The C interface is incredibly non-functional, I didn't know if that could be translated to Clojure and still be clojure-y.
14:21qbgYour if expression is also wrong
14:21qbgIt should be (empty? %) instead of empty? % in it
14:22plookneraserhd: have you seen korma? seems pretty good to me. https://github.com/korma/Korma
14:22seangrovewei__: qbg is right. (if empty? is always true, and so you just return `text`
14:26qbgom.dom/wrap-form-element seems to be doing something weird
14:31eraserhdplookn: Maybe I'm old, but I was hoping for something like -lgdbm, and not something SQL-y.
14:31wei__(inc qbg)
14:31lazybot⇒ 4
14:31wei__(inc seangrove
14:31wei__)
14:32wei__oops
14:32wei__(inc seangrove)
14:32lazybot⇒ 2
14:33gfredericksdoes anybody know under what conditions (compilation, repl, lein details, etc) a compile error would cause just the single line "Subprocess failed" of output?
14:34seangroveOut of negative karma at least
14:35wei__(dec seangrove)
14:35lazybotYou want me to leave karma the same? Fine, I will.
14:38iwofinally google fu revealed the name, it was John Lawrence Aspden
14:42qbgCan anyone else reproduce my Om issue, or see a problem in this code? https://gist.github.com/qbg/9295942
14:52seangroveqbg: What do you mean controlled/uncontrolled?
14:53qbghttp://facebook.github.io/react/docs/forms.html
14:53qbgIn the Gist posted, you shouldn't be able to change the text
14:54seangroveqbg: Ah, I see
14:56seangroveqbg: Just as a guess I'd say that dom/input is actually a component with its own :onChange, etc.
14:56wei__not sure, but I think I might be running into a similar issue here: https://gist.github.com/yayitswei/9294380#file-gistfile1-clj-L47
14:56qbgseangrove: It is. Check out om/wrap-form-element
14:56qbg*dom that is
14:57seangroveqbg: Yeah, looking at it. We use sablono, which I believe skips om/input|textarea, etc.
14:57wei__you're not supposed to be able to enter non-numeric characters, but the textbox still changes
14:58ptcekIs bidi a feasible alternative to compojure?
14:58qbgwei__: I produced that gist above from reducing down your code :)
14:59wei__oic :)
14:59kevinfishwhy am I getting this error: https://pastebin.sabayon.org/pastie/16528 when I try and do this: http://mmcgrana.github.io/2010/07/develop-deploy-clojure-web-applications.html ????
14:59seangroveProbably good to ask dnolen_ what the idea behind om.dom/input is, how to use it, etc.
14:59wei__qbg: it works as expected in the Om tutorial though
14:59dnolen_seangrove: it fixes React input for async rendering
15:00seangroveThe value for om.dom/input is set from local state
15:02wei__kevinfish: try upgrading your clojure version?
15:02wei__also, not sure if contrib is supported anymore
15:02qbgyikes, 1.2.0 is pretty old
15:06qbgdnolen_: Any thoughts on my gist? https://gist.github.com/qbg/9295942
15:07kevinfishhow do I do the project.clj so it just uses the newest of everything?
15:07kevinfishjust leave off the string version numbers?
15:08qbgkevinfish: I'm not sure you can, and if you could you wouldn't want to anyways
15:09qbgSince you wouldn't want your project to break just because someone released a new version of <insert library here>
15:11kevinfishqbg: k, do old versions ever cease to become available or to work?
15:11qbgThey shouldn't
15:12qbgat least for releases
15:12dnolen_qbg: nothing much we can do about that, if you implement onChange you must call om.core/set-state! or om.core/transact in order to force a re-render
15:13dnolen_even if the value doe not change
15:13dnolen_qbg: using React input does not work at all, the cursor will move
15:13dnolen_I mean the input cursor (not Om cursors)
15:13wei__kevinfish: I was actually looking at this article the other day. here's a version that compiles & runs, though I didn't try to fix the functionality: https://github.com/yayitswei/adder
15:16wei__dnolen_: does om/update! also force a re-render even if the value doesn't change? e.g. https://gist.github.com/yayitswei/9294380#file-gistfile1-clj-L37
15:17awalkerundocumented (surprising?) feature of let: it evals body in a do. I feel dumb for just now discovering this, but since let is a special-form, it's impl is in Compiler.java
15:17dnolen_wei__: update! just defers to transact! and yes
15:17kevinfishwei__: k, thx, I'll try it
15:19wei__kevinfish: btw lein-ancient does what you want re: checking for latest versions. though from experience I usually hit a lot of errors when I blindly upgrade everything at once
15:20awalkerI suppose it should have been obvious from ~@body or from exprs* in ":forms '[(let [bindings*] exprs*)]" in what little is visible in core.clj
15:21bootheadHi folks, I'm looking into the viability of building the front end of a web app in clojurescript. Anyone have any experiences (good or bad) they'd like to share?
15:23bbloomseangrove: i think that's your cue :-)
15:25kevinfishwei__: k, thx. One at a time is the key :)
15:25bbloomboothead: in summary. Om, although young, is the best thing out there for client-side app dev, bar none
15:26wei__*if you know Clojure
15:26bbloomwei__: true.
15:26bootheadbbloom, for what reasons? how about reagent?
15:26bbloomi haven't looked at reagent closely, but let me clarify that cljs+react = best thing
15:26bootheadwei__, oh dear. however the backend is written in Haskell so how hard can it be ?:-)
15:27bbloomboothead: ha. answer is: much easier, once you un-type-poison your brain
15:27bootheadbbloom, thems fightin words! ;-)
15:28dnolen_boothead: Reagent is very cool, Om is a bit more opinionated with respect to state management
15:29dnolen_boothead: and some neat stuff fall out of that, like being about able to subscribe to all state transitions, and component construction interception falls out of breaking away from how React components are constructed.
15:29bootheaddnolen_, as I haskeller I approve of opinionated state management (obviously) what are om's opinions?
15:30dnolen_boothead: as much as possible state transitions transition the entire application
15:30dnolen_app state -> function -> new app state
15:30bootheadalso as a haskeller comfortable with lots of symbols in my code I have no idea what this save #(let [v (-> @val str clojure.string/trim)] might be saying
15:30bbloom~reader
15:30clojurebotreader is http://news.ycombinator.com/item
15:30bbloomboo
15:30bbloomclojurebot: forget reader
15:30clojurebotGabh mo leithscéal?
15:31dnolen_boothead: well that a different problem, learning the language, https://github.com/swannodette/lt-cljs-tutorial
15:31bbloomclojurebot: reader is http://clojure.org/reader
15:31clojurebotRoger.
15:31bbloomboothead: that doc page will explain all the symbols, there are not many
15:32bbloomboothead: in short, # is single-expression lambda. -> is just a macro, you can (doc ->) to see what it does. and @ is shorthand for calling the deref function
15:32bootheaddnolen_, ah yes I came across that - very useful, thank you!
15:33amalloyclojurebot: forget reader |is| http://news.ycombinator.com/item
15:33bootheadbbloom, "just" a macroin the same way that a monad is "just" a moniod in the category of endofunctors? :-)
15:33clojurebotI forgot that reader is http://news.ycombinator.com/item
15:34bbloomboothead: no, it's just a fucking macro. it takes some bit of code and injects it in to the data structure that represents another bit of code, then evals it. it's brain dead simple
15:34bbloomboothead: if you can understand cut/paste, you can understand macros enough to use them
15:34bootheadactually dnolen_ state -> function -> new state isn't that dissimilar from how the backend works
15:38bootheadbbloom, ok so from ([x] [x form] [x form & more]) I deduce that (-> 1 str clojure.string/trim) is the same as saying (clojure.string/trim (str 1))?
15:38qbgyes
15:38bbloomboothead: use macro expand to confirm:
15:38bbloom,(macroexpand '(-> 1 str clojure.string/trim))
15:38clojurebot(clojure.string/trim (str 1))
15:38bootheadso why what's the trade off in writing it the other way?
15:38bootheadah nice!
15:39bootheadand what's the "," at the beginning for?
15:39bbloomboothead: similar use cases as $ in haskell: convenience of notation, evaluation order, etc
15:39bbloomthe , is a directive to clojurebot
15:39bbloom,5
15:39clojurebot5
15:39bbloom5
15:39bbloom&"is for lazybot"
15:39lazybot⇒ "is for lazybot"
15:39bbloomin clojure, commas are normally just whitespace
15:39bootheadah cool thanks!
15:39bbloomand & is just an ordinary symbol, although it is generally used for "rest args" notation in many places
15:41bootheadis there a recursive version of macroexpand? I get (clojure.string/trim (clojure.core/-> 1 str)) in the repl
15:41bbloom,(clojure.walk/macroexpand-all '(-> x y z w))
15:41clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk>
15:42bbloom,(require 'clojure.walk)
15:42clojurebotnil
15:42bbloom,(clojure.walk/macroexpand-all '(-> x y z w))
15:42clojurebot(w (z (y x)))
15:42firefauxis there a function like map-invert which keeps all duplicates?
15:43firefauxso instead of (map-invert {:a 1 :b 1}) => {1 :a}, I want (map-invert* {:a 1 :b 1}) => {1 #{:a :b}}
15:44amalloy&((fn map-invert [m] (apply merge-with into (for [[k v] m] [v #{k}]))) {:a 1 :b 1})
15:44lazybotjava.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry
15:44amalloy&((fn map-invert [m] (apply merge-with into (for [[k v] m] {v #{k}}))) {:a 1 :b 1})
15:44lazybot⇒ {1 #{:a :b}}
15:44gfredericks,(macroexpand-1 '(-> x y z w))
15:44clojurebot(w (z (y x)))
15:45gfredericksboothead: that less helpful output is better in 1.6
15:45bootheaddnolen_, the question you've just been asked on twitter is pretty much the pattern that we've been talking about an event propagates causing the whole state of the world to be updated (also pretty similar to FRP). that's how we've built our back end and i'm hunting for a similar abstraction for the front end
15:45gfredericks&(macroexpand-1 '(-> x y z w))
15:45lazybot⇒ (clojure.core/-> (clojure.core/-> x y) z w)
15:45bootheadthanks bbloom!
15:46dnolen_boothead: well that's how Om works
15:46firefauxamalloy: that's wonderful
15:46firefauxamalloy: now I'll have to figure out exactly how it works
15:46dnolen_boothead: modularity is an issue with world passing style so Om implements a Lens like thing so that components only see the part of the world they should be concerned with
15:47bootheaddnolen_, the cursor right?
15:47dnolen_boothead: yep
15:47bootheaddo you happen to know anyone who's supped the cool aid and is now looking for someone to pay them to use it in anger?
15:48dnolen_boothead: people already using it anger
15:49piranhawhat's the simplest way to serve compiled cljs using same lein? is there anything like python's SimpleHTTPServer or should I write a ring app and use lein-pdo to run that?
15:49bbloomdnolen_: that instrumentation thing is nice. recover the (small amount of) useful parts of aspect-oriented-ish-ness lost when leaving the css selectors approach of jquery behind :-)
15:50dnolen_bbloom: yep
15:50bootheadmy experience in hiring for haskell is that for the really good cutting edge tech there tend to be a lot more great people who put the effort into learning something for the love of it than people who can get a job in it.
15:51dnolen_bbloom: and it's selectors over something useful, your components, not the stupid DOM
15:51bbloomdnolen_: true fucking story
15:52gfredericksboothead: I think cemerick's survey says that the proportion of industrial use is rising significantly
15:53bootheadgfredericks, i hope so! I'm doing my bit to help (hopefully) http://www.meetup.com/London-Start-Up-Functional-Programmers/
15:56dnolen_piranha: a lot of people seem to pair CLJS with Ring
16:00piranhadnolen_: hm, ok
16:15gfredericksI think it might be unwise to deal heavily with the
16:15gfredericksclojure compiler without a java IDE
16:35bacon1989Hi, is there a simple way to do an outer join between two sequences?
16:36bacon1989like I have a range 1 to 10, I want to get a list of [[1 1] [1 2] ... [10 10]]
16:36bacon1989I feel like i'm not approaching this correctly, and it seems like a rather simple problem
16:37gyimlike this? (for [i (range 1 11) j (range 1 11)] [i j])
16:38bacon1989haha yes
16:38bacon1989I didn't know for was like a list comprehension
16:38bacon1989thank you, that should get me in the right direction
16:38bacon1989much appreciated
16:38gyim(y) you're welcome
16:44TimMcgfredericks: Ooh, what are you up to that involves looking at Compiler.java? At work I'm trying to get it to compile gen-class namespaces.
16:51pepijndnolen_: guess what. someone is paying me to play with core.logic :D
16:55goldfelddnolen_: does om + pedestal make any sense to you?
17:04Rich_MorinI've been playing with using a router-like globbing syntax to navigate trees of arrays and lists - http://wiki.cfcl.com/Projects/Ruby/Tree_Globbing I'm wondering if anyone else has done anything similar.
17:12gfredericksTimMc: just working on tickets; CLJ-1347
17:13bbloomRich_Morin: i hesitate to mention it... but just your comment & title sounds to me like XPath/XQuery/etc
17:14bbloombut generally, i've felt the urge for a clojure-ish tree selector syntax before
17:14bbloomalthough i can't recall the use cases now, i do recall that ultimately i needed domain-specific semantics
17:16Rich_MorinMy page mentions XPath, as well as the Unix shell. I also mention the Rails (etc) router syntax.
17:18Rich_MorinClearly, there is a lot of precedent for using globbing (etc) on tree structures; I just haven't seen it used on (say) data structures imported from JSON or YAML.
17:18TimMcgfredericks: While you're at it, any insight on why calling (Compiler/compile ...) on a namespace source string with a :gen-class wouldn't produce that class?
17:18justin_smithhttp://stackoverflow.com/questions/22120527/outofmemorryerror-when-using-seque-function any clue why the code in the question would generate 1.2 billion and counting bytes of clojure.lang.PersistentHashMap$INode[] instances?
17:18bbloomRich_Morin: is your goal for this to work on arbitrary clojure data? ie a general purpose selector syntax, as xpath/query are to xml ?
17:18justin_smithit's someone else's SO question, but I think it is exposing a bug in the compiler / implementation
17:19bacon1989question, if I have a seq and I perform something like (first (filter [pred] xs)), is it guarunteed to only process as far as the first filtered item stored in the returned list? Will it continue to evaluate the entire list even though i'm only asking for the first value?
17:19justin_smithbacon1989: thanks to chunking it could read a bit further than the element asked for
17:19justin_smithbut never the whole thing
17:19bbloomRich_Morin: either way, the -in family of functions (get-in, update-in, etc) are a sibling of the tree-selector idea. as are functional "lenses"
17:19Rich_Morinbbloom: almost - to use globbing, you want to start with a tree (or at least a DAG).
17:20bacon1989ok thanks, i'll see how well it performs
17:20bbloomRich_Morin: sure, i don't believe in cyclic values :-P
17:21TimMcgfredericks: I'll dig into it more at work, but I figured I'd ask in case you already knew. :-)
17:21justin_smithbacon1989: if an expensive op is producing the lazyseq I think there are options for preventing chunking
17:22Rich_Morinbbloom: So, for example, get-in could be extended with some form of wildcard syntax.
17:22bbloomRich_Morin: yup
17:23bbloomRich_Morin: be careful though to include an escaping syntax too then :-)
17:23bbloom(query-in a-map [:foo wild :bar])
17:23bbloomvs: (query-in a-map [:foo (literal wild) :bar])
17:24bbloomseems like a pretty straightforward thing to build
17:25the-kennyIs there a nicer way than having to run three instances of lein for cljsbuild, cljx, and repl?
17:29Rich_Morinbbloom: My Ruby version takes about 200 LOC, including lots of comments.
17:29the-kennyah, there's lein-pdo.
17:29bbloomRich_Morin: sounds like about what i'd expect. can't be much more than the definition of the grammar nodes + an interpreter that amounts to reducing over a dispatch on type
17:31Rich_MorinThe code is shown in http://wiki.cfcl.com/Projects/Ruby/Tree_Globbing#Implementation
17:44AmnesiousFunesStyle question: what is the canonical formatting for cond pred/expr pairs for large or nested forms?
17:44bbloomAmnesiousFunes: weeee
17:44bbloomAmnesiousFunes: nobody seems to agree :-P
17:45AmnesiousFunesbbloom: Will I be considered a heretic if I align the exprs vertically?
17:45bbloomAmnesiousFunes: nope
17:46AmnesiousFunesbbloom: Excellent, thank you.
17:48seangrovebbloom: What's the idea behind :instrument in Om?
17:49seangroveAsking you since you seem to get it and I haven't seen anything written about it so far
17:59gfredericksTimMc: do you set *compile-files* or whatever that var is?
17:59gfredericksTimMc: do you get other class files associated with the namespace as a result?
18:23bbloomseangrove: it's an aspect-oriented programming feature, where some function is applied to all components
18:23bbloomseangrove: essentially an instrumentation function runs on all components and has the opportunity to decide if it wants to change or wrap the component in some way
18:24seangrovebbloom: Interesting. And there's a way to selectively apply the instrumentation functions?
18:24seangroveThat would be fantastic
18:25bbloomseangrove: well, no instrument function is just the identity function
18:25bbloomwell, three argument identity
18:26bbloomyou're just intercepting every call to build
18:26bbloomyou can run any predicate you want to decide what to do
18:26devnwow, purnam looks awesome
18:27seangroveHrm, I see. I'll have to take a look at what that looks like in practice. Would it be easy to only instrument on particular set of components, or a subtree, etc.?
18:28bbloomseangrove: sure, you can filter by cursor or whatever or whatever, then just inject whatever you like
18:29seangrovebbloom: got it, sounds pretty nice
18:29seangrovebbloom: In the meantime, have you seen React DevTools with Om? Pretty nice until Om-specific tools popup
18:30bbloomseangrove: haven't tired them, got a video?
18:30seangrovebbloom: I'll send a screenshot in just a second
18:30bbloomoh i guess i can try it on fb
18:30seangrovebbloom: Current version doesn't work with Om, just got the patches into master yesterday
18:30bbloomseangrove: awesome
18:31bbloomtrying it on fb now
18:32bbloomthat's freaking awesome
18:34bbloomseangrove: remind me to bug dnolen_ about the implications of instrument on react's diffing algorithm. seems like you can get yourself in to trouble with instrument if you do conditional wrapping b/c react only identities moving elements within a single parent
18:34bbloomre-parenting is possible, but would require a more sophisticated id generation scheme
18:35bbloomgotta go, cya
18:36seangrovebbloom: When you get back http://dl.dropbox.com/u/412963/Screenshots/d4.png
18:47TimMcgfredericks: I wasn't setting *compile-files*; it would be nice to do this with Clojure I get from a DB instead of from the filesystem. I'll give that a try, though!
18:48seangrovednolen_: How can we get (om/build-all to give a unique key to each component?
18:48Nyyxanyway to use map as a bimap?
18:49dnolen_seangrove: map over elements to build + some key generator
18:49petehuntseangrove: dnolen_: react generates one
18:49petehuntthis._rootNodeId i believe
18:49seangrovednolen_: map om/build rather than (om/build-all ?
18:49dnolen_seangrove: yes
18:50petehuntyou may need to add this._mountDepth in there too
18:50seangrovednolen_: Alright, got it. Won't that by default mean that build-all is going to hurt performance?
18:50dnolen_seangrove: no, it generates a key for you.
18:50dnolen_seangrove: but it's just based on index
18:50dnolen_seangrove: which will screw you if you do insertions etc
18:51dnolen_bbloom: I don't follow the instrument thing
18:51seangrovednolen_: Looking at it in the RDT, I don't see any react-keys associated with the components
18:51dnolen_bbloom: though we'll see how useful instrument is in general case
18:51dnolen_bbloom: I'm starting to identify some cool possibilities
18:52dnolen_gotta run
18:53seangrovednolen_: When you get back, I'm curious know how :key and :react-key interact - it seems like om's :key isn't passed on to react at this point
18:56Nyyxbimaps?
18:58gfredericksTimMc: "files" refers to the target of compilation, not the source
18:58gfredericksTimMc: (source gen-class) makes it obvious that gen-class is a noop when *compile-files* is falsy
19:15muhoowhat the idiomatic way in om and core.async to check the current application state at every iteration?
19:15muhoojust deref the atom?
19:15muhooit felt to me like that'd be considered un-om-like.
19:16seangrovemuhoo: What are you checking?
19:16seangrovemuhoo: Worth checking out https://github.com/sgrove/omchaya/raw/master/docs/resources/omchaya_flow.png
19:17muhooseangrove: thanks, what you are working on there is extremely exciting
19:17seangrovemuhoo: We have 3 swaps! in our Omchaya, and 2 derefs
19:18muhoowhat i'm checking is a :run? flag in the state
19:18seangrovemuhoo: Cool stuff every day. Stole an idea from petehunt that took 4 minutes to reproduce https://dl.dropboxusercontent.com/u/412963/om_save_restore.mov
19:18seangrovemuhoo: But when/where?
19:19muhooseangrove: https://www.refheap.com/49856
19:19muhooit's just a toy, i'm learning om
19:19seangrovednolen_: Having trouble getting wrap-form-element to return a class that handles displayName properly
19:20seangrovemuhoo: I'd pull it out into a centralized controller, but otherwise I don't think you have much choice to deref in the IWillMount
19:22muhooom is making me cry with joy. i've found web-based front-end development-- indeed all UI development-- so unpleasant that i've avoided it over the past decades, and focussed on back-end development. now with om i'm finding front-end's and UIs fun and i am starting to love it.
19:23seangrovemuhoo: Same here. It's all mainly enabled by react, but Om forces an extra layer of good decisions
19:24muhooit was a natural convergence. just watched peter hunt's talk last night.
19:24muhooimmutability, composability, intelligent handling of state, what a natural fit for clojure(script)
19:25seangrovednolen_: Never mind, it's sablono copying/pasting Om code
19:26seangroveI love hiccup, but Sablono is definitely harshing my frontend a bit
19:26muhooseangrove: when are you planning for omchaya to be release-ready? i know some people who were looking for a chat system, and kanban + omchaya would be sweet
19:26gtrakwhat am I missing with austin? when I start a repl, the C-u source shows an empty script tag, which I assume is supposed to be compiled cljs. then it tries to find clojure.browser.repl, which obviously doesn't exist.
19:27seangrovemuhoo: I'd like to have a datomic backend in place (or maybe a pluggable postgres one so it's a simple copy/paste to deploy it to Heroku), and some blog posts. Going to write the first few this weekend.
19:29muhooseangrove: sweet, thanks.
19:29seangrovemuhoo: I don't think the chat industry is ripe for disruption, it's just a very good example app. And as a side-effect we can make it very nice :)
19:29riz_hi, can somebody explain to me benefit of using "recur" as opposed to just calling the function itself to do recursion?
19:30amalloyriz_: stack overflows
19:30seangroveI want to get a StackPanel component going as per bbloom's suggestion so we have a generic Overdraw/culling component for very, very fast apps without thinking about it
19:30Nyyxriz_: try doing it without a recur but make sure you loop 10000 times
19:30seangroveKandan is a perfect app to get that setup initially
19:31Nyyxand then do it with recur
19:31riz_ok
19:31seangroveriz_: There are some languages that can recur with `recur`, but for a few reasons, clojure requires it. As a positive side-effect though, it can tell you when you're recurring wrong and are going to blow the stack
19:39seangrovednolen_: Can I get you to release a point release of Om with displayName support so I can submit a PR to Sablono with support that fixes its version of om-input?
19:39seangrovednolen_: Specifically this needs to be modified https://github.com/r0man/sablono/blob/master/src/sablono/interpreter.cljx#L11
19:40riz_ok thanks guys
19:40riz_i think it makes sense
19:40greg`i just watched rich hickeys talk on the functional database really liking the datomic stuff
19:40ruzurich can get me to like anything
19:41greg`lol he really is an intelligent and charasmatic character
19:41gtrakthe compiled client.js is just empty..
19:41greg`im quite new to clojure has anyone here used datomic?
19:45muhoogreg`: many have. best to just ask your question.
19:46muhooi've used it, and enjoyed it a lot
19:46bjorkintoshgreg`, it came from prolog, don't forget.
19:47greg`what do you mean y tha bjorkintosh
19:47greg`i gueess i just want to ask do you think it would scale
19:47greg`its it like some driver that can connect to more tradiitional db's itstelf or is it a ful dbms
19:48bjorkintoshscale? do you have a scaled userbase already?
19:48bjorkintoshif not, don't worry about that, and just learn it well.
19:48muhooit scales ridiculously when you use the amazon db backend :-)
19:49muhooonly weakness i've found is that it is a memory pig for small apps or cheap vps'es. and of course it is expensive if you want the pro features (like the amazon backend)
19:50greg`are there any docs athat outline how it works technically, obviously there is some abstraction to him passing databases around, they might be streaming or proxies, just interested in how it works
19:50bjorkintoshdatalog.
19:51muhoogreg`: http://docs.datomic.com/ really, read the docs, play with it. it'll be worth your time. if you've used other systems, you might even find it fun compared to those.
20:05gtrakI think I fixed austin for cljs master :-)
20:06gtraknow I'm getting my nice tooling in a brepl.
20:17kopasetik
20:17kopasetikoops
20:17gtrak~guards
20:17clojurebotSEIZE HIM!
20:18kopasetik*runs in the other direction*
20:18gtraknow I just have to learn Om..
20:19dsrxom works so well with repl development
20:19dsrxlike, absurdly well
20:19kopasetikcurrently taking a ruby on rails class, but i look forward to really getting my hands dirty with clojure a few months later
20:20kopasetikso far i've just set up my dev environment (leiningen, etc)
20:21gtrakdsrx: what's the latest and greatest resource on it? Been looking at omchaya.
20:21kopasetikhas anyone read "joy of clojure?"
20:21gtrakkopasetik: great book
20:21TimMcgfredericks: Hmm! I don't get what you mean about targets of compilation, but I'll take another look at gen-class' source.
20:22gtrakkopasetik: Not a beginner's book though.
20:22gtraktook me a while to get through it, but it was good stuff.
20:22seangroveJesus, is Omchaya already dated?
20:22kopasetikgtrak: great to know
20:23gtrakseangrove: I mean.. I can read it and see how it works, np.
20:23gtrakI started to go through the git commits to try and grasp how it got built.
20:23seangrovegtrak: Yeah, haven't been goot about the commits
20:24gtrakI'm just impatient and ADD, in general.
20:24seangroveMost of the patterns were lifted from our production app
20:24gtrakwondering if there's any elucidating blog posts since the last time I looked.
20:24kopasetikgtrak: is there a clojure book that you'd recommend to beginners?
20:24gtrakI heard 'Clojure Programming' is good.
20:25kopasetikgtrak: cool
20:25kopasetikHas anyone here tried coding w/ clojure for android products?
20:26gtrakkopasetik: last I could tell it wasn't production-grade.
20:28kopasetikgtrak: so it doesn't make sense to use clojure to make android apps, huh?
20:28gtrakbeen meaning to try cljs with phonegap again :-).
20:29kopasetikcool
20:30kopasetikanything i can do to minimize the amount of java i'd have to code... :-P
20:30gtrakit's relatively easy to get a REPL running in phonegap, took me about an hour to figure it out.
20:31gtrakbut basically you have to have something serve the dev-html so cross-origin isn't an issue.
20:31gtrakI suppose you could also do it with jsonp.
20:31seangrove$mail ddellacosta Interesting: In Sablono, you have to pass {:key "whatever react key for the element"} for [:built-in-tags ], but you have to pass {:react-key ...} to om/build components
20:31lazybotMessage saved.
20:32kopasetikgtrak: ok
20:34kopasetikgtrak: about how much of your clojure coding is repl-based?
20:34gtrakall of it
20:35kopasetikwow. that sounds awesome.
20:35gtrakas opposed to running unit-tests from cmd-line?
20:35gtrakor what?
20:36gtrakone of the unfortunate things about clojure is it's too slow to do anything else :-
20:36gtrak:-)
20:37kopasetikyeah, vs jumping back and forth between a text editor and the command line
20:37kopasetikwell, that's one of the consistent drawbacks of functional programming, isn't it?
20:37kopasetikit's powerful and expressive, but it runs slowly right?
20:38gtrakit runs fast actually, it just starts up slow. Almost bearable in small projects.
20:38gtrakwhen I was playing around with cljs last, I did the lein-cljsbuild and refresh the web page thing a lot.
20:38RickInAtlantait is the jvm that is slow
20:38RickInAtlantaon startup
20:38gtrakbut I hope to stay on the repl now.
20:39RickInAtlantagtrak: connecting to a browswer in LightTable is pretty cool. ctrl+enter and the dom updates
20:39gtrakneat
20:40gtraklight table's just calling the cljs compiler itself?
20:40RickInAtlantathe Om tutorial is a good demonstration of that https://github.com/swannodette/om/wiki/Basic-Tutorial
20:41RickInAtlantawhether or not you are using LightTable, one good way to work with ClojureScript if you want to check things in the browswer is to use lein cljsbuild auto, your js compiles every time you save a change
20:41dsrxgtrak: if you're using cider or whatever you can just C-c C-c the appropriate expressions too
20:41gtrakyea, that's what I used to do and hope to avoid.
20:41RickInAtlantacompiling is really fast
20:41dsrxor C-c C-k and send the whole namespace over
20:42locksthe Om tut is very nice
20:42dsrxs/namespace/file
20:45RickInAtlantato compile clojure code, you need java 6 right? Need jdk, or just jre?
20:46AimHereJust the runtime
20:47ruzu6? bah!
20:47RickInAtlantathx
20:47gtrak7's a bit faster, using 8 myself.
20:47AimHereleiningen is hugely recommended if you're doing anything but anything in clojure
20:52ruzuleiningen's monopoly is unhealthy :P
20:53locksruzu: time to make an alternative
20:53gtrakit's a natural monopoly
20:54gtrakthere used to be 'cake'
20:55gtrakthere's always maven..
20:56justin_smithcompared to the many ways of managing dependencies in js, having a definitive widely used option in clojure is better (better for reliability, ease of deployment, and dev environment setup)
21:01ruzusure, there are benefits to One True Way :)
21:01amalloyif you enjoy pain, ruzu, you can always manage your classpath and invoke java manually
21:06seangroveAlright, got all of the "missing keys" warning from react taken care of, sablono is doing something very strange that requires special {:key ...} attrs almost everywhere. Adds a lot of visual noise
21:08gtrakhrm.. is it a known issue of austin that the env doesn't stick around after a refresh?
21:09gtrakI guess that makes sense, but it is le-suck.
21:10gtrakseems like it could dump the analyzer state to the client-js on a refresh.
21:16seangrovegtrak: That's a feature in Omchaya as of yeserday
21:17gtrakhow'd ya do that?
21:17seangroveOptional persisting/restoring of state
21:17gtrakI want the actual repl state.
21:17gtraknot just app state :-)
21:17seangroveHrm... for example?
21:18gtraklike... if I refresh the webpage, it throws out the JS environment, which throws out all loaded cljs and closure code.
21:18dsrxgtrak: really?
21:18dsrxthat doesn't seem right
21:18gtrakmaybe I broke something, I'm using custom builds. Since piggieback actually manages the compiler env, stands to reason it could also emit more JS for the reconnect.
21:19seangrovegtrak: I see, I usually have the two things be the same
21:19gtrakwhich two things?
21:21seangroveLoaded cljs definitions/app state. Any changes to the source files are compiled out to the fs, so a refresh will reload the current version. Then the app state will be reloaded to the point I was at
21:21gtrakah, yea. I'm not using the FS at all for this, except source.
21:21gtrakseems like it could be made to work.
21:21gtrakthen I'd have a smooth clojure-like experience :-)
21:22dsrxgtrak: piggieback does not manage the compiler env
21:23gtrakhow do you figure?
21:23gtrakI rely on that for my auto-complete impl.
21:24dsrxpiggieback holds onto an IJavaScriptEnv record that manages the compiler/analyzer state, but that's all created + implemented in austin
21:24seangrovegtrak: As an aside, the auto-complete can't query the js-runtime about available symbols, right?
21:24gtrakseangrove: nope, it doesn't.
21:25seangroveDefinitely want auto-complete, and even just cljs-only is a great step forward. Querying the live env is the next piece though, very nice for exploratory programming
21:25gtrakhere we go:https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/middleware/util/cljs.clj#L17
21:25gtrakit's in the nrepl session.
21:25gtrakseangrove: I can live without the JS env for now.
21:26seangrovegtrak: Oh yes, definitely far better than the current state
21:26dsrxgtrak: yeah, as I said piggieback holds onto a repl-env, but it doesn't manipulate its state or anything like that
21:27gtrakpiggieback implements the nrepl load-file eval stuff.
21:27gtrakaustin uses piggieback as a backend.
21:27dsrxgtrak: it implements the nrepl front end for the load-file
21:27dsrxbut actually loading the file into the repl-env is delegated to the IJavaScriptEnv
21:28gtrakdsrx: that's the JS
21:29gtraknow, if you mean to say, JS couldn't be re-derived from analyzer state and loaded back into the IJavaScriptEnv like I'm proposing, that's another problem :-).
21:30RickInAtlantadoes anyone know if there is a "table of contents" page for Clojure From the Ground Up
21:36gtrakdsrx: hrm, trying to figure out where the analysis result gets swapped into the compiler-env again.
21:39gtrakpiggieback tacks it on to the rhino env at least, I think the cljs compiler itself updates it. checking austin now.
21:41gtrakaha!
21:41gtraksame key: https://github.com/cemerick/austin/blob/master/src/clj/cemerick/austin.clj#L399
21:44dsrxI think piggieback (and austin, when loading initial state) hands off to cljs.repl/evaluate-form, which hands off to the analyzer which dumps its state in env/
21:44dsrxoops
21:44gtrakso, the whole story is austin initalizes the repl env like you said, but piggieback exposes it by setting up some dynamic vars. Seems like on an austin session reconnect we could emit a JS string from the analyzer corresponding to the nrepl-session that started the austin session. phew..
21:45gtrakthen the browser could load that instead of a blank slate.
21:45dsrxgtrak: so you're after something like, open an austin repl, send some new vars to it in cljs.user, then on refresh those vars are available again to the browser?
21:45gtrakyea
21:45gtrakexactly
21:45dsrxahhh, nice
21:46dsrxI'm not terribly familiar with the analyzer internals, but that seems reasonable to me
21:46gtrakwell, here's the real problem, the compiler thinks things are loaded that aren't, so when I try to reload a file, it doesn't quite work right.
21:46gtrakIE I think transitive deps don't get reloaded into the browser.
21:47gtrakmight be an easier fix to just clear the compiler state, but not as fun :-)
21:49gtrakI'll have to go bother Chas later.
21:58seangrove$mail ddellacosta check out https://github.com/r0man/sablono/issues/18
21:58lazybotMessage saved.
22:02bbloomseangrove: so i'm not sure if i understand sablono.... other than the #js literals for react props is less than ideal
22:03bbloomif i understand correctly, sablono only works for dom nodes, but not components, right?
22:03seangrovebbloom: Exactly, which I'd like to see rectified eventually, but haven't got to it yet
22:04seangroveIdeally you should be able to specify [:my-component {:opts ... :key ..}] like any other primitive DOM element, and it should look up the current implementation in a registry somewhere
22:04bbloomseangrove: hm, i feel like with a hook or two, react could be made to handle clojure maps as props & then main issue would go away. at which point i don't see why [] is better than ()
22:05seangrovebbloom: I'm partial to hiccup syntax, but I've been waffling about that as well.
22:05bbloomseangrove: well hiccup mainly makes sense b/c the entire tree must be reified and manipulatable
22:05bbloomseangrove: however, with the react model, you intentionally want encapsulation
22:06bbloomfurther, the react internals won't regenerate, or rehydrate, or traverse, or even consider, the subtree if it's not necessary
22:06seangrovebbloom: IO
22:06bbloomso splicing, is only really useful for the children sequence at most
22:06seangroveWhoops. I like the idea of having data structures that may be transformed very easily.
22:07bbloombut in that case, i rather maps than the hiccup syntax
22:07seangrovebbloom: For example, in this case, it was very handy to have clojure data structures to operate on https://github.com/sgrove/omchaya/blob/master/src/omchaya/plugins.cljs#L62
22:08seangroveI don't know if it's all worth it though
22:08bbloomseangrove: sure, but hiccup is syntax, which is annoying b/c you have to detect & deal with the optional map value
22:08seangroveStill feeling it all out
22:08seangroveTrue
22:08bbloommy original design (prior to react and looong before om) was a rewriting model
22:09seangroveRather than {:attrs .. :content ... :etc ..}
22:09bbloomwhere type/props/children/state/etc == just one map merged as appropriate
22:10bbloombah, i can't explain it here
22:10bbloomone of these days i'll have to finish that project
22:10bbloomi could probably make it work great directly on react w/o the loads of other stuff i had planned on....
22:10bbloommaybe i'll just make a proof of concept & let somebody else do the rest of the work :-P
22:10seangrovebbloom: Make a note to tell me when you're out here, I'm very curious to explore this space right now
22:12bbloomseangrove: let me see if i can get a bit of the idea out...
22:12bbloomcomponent instances would be maps and they'd be rewritten according to some simple rules
22:12seangroveWhat kind of rewrites, and what kind of rules?
22:13bbloomtrying to think up a good example
22:13seangroveLike a macro-expansion process?
22:13bbloomyes
22:13justin_smithI'm wondering why the code from this http://stackoverflow.com/questions/22120527/outofmemorryerror-when-using-seque-function is doing this: http://i.imgur.com/gHJ6col.png
22:13bbloomseangrove: so an example would be the "prototype" property, which would be reverse-map-merge
22:13justin_smithlooks like it is leaking, mainly leaking char, but also leaking object, byte etc.
22:13seangrovebbloom: I has a very similar idea sketched out as well
22:14justin_smitheventually it dies with a heap error, as that SO post notes
22:14bbloom{:prototype :button :text "hello"} could expand to {:template (fn ...) :text "hello"}
22:14bbloomand then templates would be called given the rest of the object
22:15bbloomso the button template might be (fn [{:keys [text]} {:html/element "div" :css/margin "5px" :children {:html/element "span" :html/content text}})
22:15bbloomfor example
22:16bbloomprototypes would be applied as reverse merges until prototype was nil, then templates recursively expanded like macros, along the way various properties would trigger various other rewritings
22:16bbloomthen the result would be shallow, just like in react, and the result would get rendered
22:17bbloom(fn [{:keys [text]}] {:html/element "div" :css/margin "5px" :children [{:html/element "span" :html/content text}]}) ; fixed braces
22:17bbloommy plan was for this exact model to support stuff besides :html/element, like say :canvas/shape
22:17firefauxdoes anybody know where clojure.contrib/core has moved to now?
22:18bbloomif you had a :canvas/shape that wasn't inside an :html/canvas, then a rewrite rule could easily insert one :-)
22:18seangrovebbloom: Yeah, I was thinking about approaching this with multimethods, but this seems sensible
22:18bbloomseangrove: i actually have this mostly sorta working with java2d rendering and no optimizations (ie it just rerenders the full view 60fps)
22:18bbloomin that context, i had to tackle layout and everything else too
22:19bbloomseangrove: i'll show you how it all works at clojure/west
22:19bbloombasically, it's WPF without databinding lol
22:20firefauxooh, I just found that core.incubator has most if not all of the contrib/core functions
22:20seangrovebbloom: Sounds great. I think there may (possibly!) be some value to using this model to generate mobile web views from a xib package
22:20seangroveOr vice-versa
22:20bbloomseangrove: yeah, my plan was to support arbitrary display backends. just swap out the prototypes/templates
22:20seangroveExactly
22:20bbloomseangrove: i have a java2d render and a hiccup renderer
22:21bbloomjvm clj side. was trying to get the model right first
22:21bbloomthen react came out and i stopped working on it lol
22:21bbloomi was like "OK, i'll just wait until the rest of the world understands what it took me 2 years of thinking to understand... then they will be ready for this" lol
22:22seangrovebbloom: Well, I think they more or less got it on the desktop, but certainly not in the browser
22:22seangroveAnd maybe not even in the desktop... but certainly closer there :P
22:22bbloomseangrove: you kidding? the desktop frameworks aren't anywhere near react
22:23bbloomseangrove: at least in terms of semantics
22:23seangrovebbloom: Thinking about tooling
22:23bbloomtooling & functionality, oh yeah, desktop is much better
22:23seangrovebbloom: In Xcode you drag mockup components around, declaratively configure them, and get a ton of mileage
22:23bbloomyeah, but it's a sham
22:23seangroveThe description is compiled down into the actual implementation in a separate step
22:23bbloomit's very superficial declarativeness
22:24seangroveSure, but it's far better than what we've had in the browser!
22:24bbloomyeah, browser quality & perf sucks
22:24bbloomand until react, the semantics were even worse
22:24seangroveWell, and also semantics
22:24seangroveHeh, yes, exactly
22:25bbloomin game engines, they get it
22:25seangroveWhich is mind-boggling
22:25bbloomgoogle for "IMGUI"
22:25bbloomi was in here blabbing about IMGUI for months last year lol
22:25seangroveThere isn't much reuse in the game world's take, though
22:25bbloomnah, i worked in the game world. it doesn't surprise me at all that the game guys get it. it surprises me even less that they haven't been able to communicate it
22:26bbloomtake a look at Unity's ui toolkit
22:26bbloomi hear it's got it's own sorts of flaws & whatnot, but overall it's very react-like
22:26bbloomalthough it relies on the perf of gpus to be a lot less clever in it's optimization
22:26seangrovebbloom: Until major license engines like Unreal/Unity/etc. I should say, heh
22:27bbloomunity's approach is basically react's except that instead of caching state & props and whatever at the per component level, there are some privledged components for capturing textures so you can prevent re-rendering that way
22:27bbloomyou basically just render a subview in to a texture and composite
22:27bbloomwhich is much nicer than dealing with the dom :-P
22:27seangrovebbloom: Make sense
22:27seangrovebbloom: I'm pretty excited for all of the stupid work that's about to go away for web devs
22:27bbloomindeed
22:28bbloom90% of the work "engineers" do these days is glorified desktop publishing at best
22:28seangroveI feel like I want to go around rebuilding people's ui's - "Look, isn't this so simple now? And fun?"
22:28bbloomheh
22:28seangroveWe'll see when that feeling wears off, but for now it's great.
22:29seangrovebbloom: Alright, I think I'll start on the StackPanel component now. I'm still unsure about how to go about it, but I think it's time.
22:30bbloomseangrove: i'm confident you can do it!
22:30seangroveOh man, insta-state-reload is so lovely
22:31bbloomtrue story
23:15quizdrre
23:15ruzumix
23:15dsrxpl
23:16quizdrif I have a map where the values are also maps, and I want to alter the values in these values' maps, I suppose you'd need a nested for (as one option) and that you can't destructure and work with all these maps using a single for, correct?
23:24goldfeldquizdr: if you need to alter a single path down the nesting, update-in may suffice
23:33seangrovebbloom: So to implement this StackedPanel, I need to keep track of viewport size, scroll position, I have to know the height of all the widgets I'm rendering, I need to absolutely position them, and when they're in culling territory I need to render a blank placeholder of the right dimensions. That cover everything?
23:33quizdrgoldfeld thanks i'll look into that
23:34bbloomseangrove: it's much much easier if all widgets have the same, known height. start there
23:34seangrovebbloom: Yup
23:34bbloomseangrove: i don't think you need to worry about blank placeholders, just absolute position inside a way oversized container and use scroll always
23:34bbloomcss scroll-y: always, i mean
23:35bbloomstart w/ a non-virtualizing stack panel, which should be easier & show me the code & i'll help you make it virtualizing
23:35seangrovebbloom: Alright, will do
23:57dfsaiI'm just starting out clojure, being a professional js/rb/py dev. How come lispers insist on closing all parens on one line, instead of letting them close on the same indentation level as they were written? The latter, that is common in js/c and all of that seems more readable, and easy to know when you made the error of not closing a list, or closing one too many?
23:58ryantmdfsai, seems only more readable when reading backwards.
23:58ambrosebsdfsai: for one we generally have better tools to manage parens, so we don't need to be as defensive
23:59ryantmdfsai, Also, you don't mess up the parens if you use something like Paredit