#clojure log - Mar 01 2014

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:56 muhoo: http://www.youtube.com/watch?v=vWNJlc-IylY

0:58 noprompt: muhoo: this is awesome. just what i needed right now. :)

0:59 muhoo: np, glad to be of help

1:04 noprompt: i'll share a fun one too.

1:04 http://www.youtube.com/watch?v=0ObNPZy40Zw&index=10&list=LL5nj8P53p55J6VNR8STWR7A

1:06 SegFaultAX: And here's an old classic that always makes me happy: https://www.youtube.com/watch?v=uq-gYOrU8bA

1:06 noprompt: what the hell happened to good music?

1:07 damn kids these days. no taste.

1:07 haha.

1:07 what the hell happened to bass lines?

1:07 SegFaultAX: All the good music passed through the music industry human centipede-style.

1:08 And came out the other end... well, you know.

1:08 goldfeld: cellphones and crappy earbuds happened to bass lines

1:09 noprompt: oh and lyrics are pretty much dead sauce too. :(

1:09 goldfeld: also 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

1:10 i'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

1:11 SegFaultAX: You know what I wonder sometimes? Where are the Shakespeares and the Michelangelo's of our day?

1:11 noprompt: SegFaultAX: they're writing code.

1:11 SegFaultAX: It's like we're not generating enough great artist points per turn anymore. Or the threshold has gotten so high, they almost never spawn.

1:12 goldfeld: SegFaultAX: they're in heavy debt and without a job, and the age of patronage of artists is well over

1:12 SegFaultAX: goldfeld: Oh, so that's who made my latte this morning...

1:12 goldfeld: SegFaultAX: there's a non-zero probability in that

1:13 noprompt: it's also worth mentioning the general lack of focus on art.

1:13 SegFaultAX: goldfeld: That's what makes it both funny, and horribly depressing.

1:13 noprompt: Science math and engineering is all there is.

1:13 Duh.

1:13 There is nothing more to life.

1:13 noprompt: design != art and the younger generate is growing up missing out on that distinction.

1:13 (inc SegFaultAX)

1:13 lazybot: ⇒ 4

1:14 noprompt: i spent my whole life doing (weird) art. no one gives a shit an no one wants to.

1:14 goldfeld: by the way where's the Civilization of our day?

1:14 i mean it's about time a new Great Game turned out right

1:14 are all our specialists working on the next iphone hit?

1:15 erhmm, or of my day

1:15 though i think i was at least barely born back when the first one came out

1:15 SegFaultAX: goldfeld: I'm glad someone got the civ reference. :)

1:15 noprompt: my only hope is that technology will eventually lead humanity to forsake money.

1:16 goldfeld: and played the second back when i barely understood what all the things i was producing meant

1:16 noprompt: money's a bad idea.

1:16 it misplaces the emphasis on humanity.

1:18 goldfeld: SegFaultAX: 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

1:20 i fear technology will do a bit more than make us forsake money, it may well forsake opportunity

1:21 in 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

1:21 noprompt: i don't think that will be a problem

1:22 goldfeld: if all work is better done by technology, AI and robots, then the only humans standing to profit are the ones who own those

1:22 profit not necessarily in a monetary sense, but in being able to provide value

1:23 noprompt: "value" is a relative term

1:23 humans want to manifest themselves in some form or another.

1:23 i believe that is "value" enough.

1:23 when humans do not have this bad things happen.

1:24 goldfeld: but those scale across the hordes of people inhabiting this planet by that time?

1:24 but does it*

1:24 noprompt: when you can augment reality as you see and hear it why not?

1:25 goldfeld: i think i see where you're getting at

1:25 that might work indeed, though the romantic in me thinks something is lost in distancing ourselves from the 'real'

1:26 but then that's my culture from this time

1:26 noprompt: from what i can tell, man seeks control over reality. this is the primary motivation for all scientific and artistic ventures.

1:26 at least as i see it in my ignorant way.

1:26 but what is "real"?

1:26 when you dream is that not "real"?

1:27 all experience is real.

1:27 goldfeld: well some of it is not persistent enough to be real, but i see your point

1:27 a dream is not as real because it's so unstable

1:27 noprompt: so it's not real because you experience it?

1:28 experience must be real.

1:28 therefore dreams must be real because they exist within the context of consciousness.

1:29 goldfeld: i 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

1:29 noprompt: as far as anyone can tell what the do not experience is *not* real.

1:29 s/the/they

1:29 goldfeld: wherein new opportunity exists

1:29 noprompt: am i making sense here?

1:29 had a couple glasses of cognac. :)

1:30 goldfeld: you are, though i don't entirely agree that experience equates reality

1:30 oh that's fine, i had something else

1:30 noprompt: counterpoint?

1:31 goldfeld: well, if i'm sure that i'm living in the real world (or physical world)

1:32 and 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

1:32 i have experienced the room while i was there, yet i question how real it is

1:34 sure, 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

1:34 noprompt: so you don't equate sensation/experience w/ reality?

1:35 goldfeld: i have some attachment to the physical world, i'd say

1:35 noprompt: iow reality and sensation/experience are disjunct in your opinion?

1:36 goldfeld: well yes, i think experience is a part of it

1:37 i think there's a reality that's independent of me and my experience

1:41 dissipate: is this ##philosophy or #clojure?

1:42 danoyoung: I 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)?

1:42 noprompt: dissipate: that is indeed the question. :P

1:42 danoyoung: the whole line is: ((c/comp #'local-date-time->day #'string->local-date-time) ?txn-date :> ?day)

1:43 dissipate: noprompt, is it true that Clojure is based on philosophy and notions of time and reality?

1:43 goldfeld: dissipate: that's deep

1:43 seancorfield: danoyoung: #' is a variable reference

1:44 normally you only use it as a short hand for (var ..)

1:44 so #'local-date-time->day and (var local-date-time->day) are the same...

1:44 danoyoung: ok…so what is #'string->local-date-time? I'm curios about the ->

1:44 noprompt: dissipate: imho, programming languages are more or less in some what the manifestation of some philosophy.

1:44 dissipate: goldfeld, think about the notion of immutability

1:44 danoyoung: ok

1:44 noprompt: s/in/are

1:44 seancorfield: -> is just part of the variable name

1:45 danoyoung: got it....

1:45 dissipate: noprompt, what is the philosophy of Von Neumann languages?

1:45 danoyoung: thanx

1:45 noprompt: dissipate: not sure.

1:45 seancorfield: danoyoung: foo->bar is a Clojure convention for a function that turns a foo into a bar

1:45 danoyoung: ahh..thanx

1:46 seancorfield: the other time you'll see #'var-name is when pulling a private variable out of a namespace

1:46 noprompt: dissipate: but i'm sure there's something behind it. even mathematics and logic, and by extension computer science, are children of philosophy.

1:46 seancorfield: since there are no really private variables in Clojure

1:48 danoyoung: ok…thanx for sharing...

1:48 dissipate: seancorfield, variables don't need privacy. BTW, isn't the 'proper' term symbol?

1:48 seancorfield: yes, technically

1:49 groovy has the right idea: private is "advisory"

1:49 noprompt: seancorfield: what is your position on ^:private these days?

1:50 seancorfield: I'll use ^:private on some implementation-specific data but I no longer write private functions

1:51 dissipate: noprompt, if Clojure was a location on Earth, where would it be?

1:51 seancorfield: right now about half our functions are private but i expect that to change

1:51 Clojure source 99 files 17235 total loc,

1:51 1261 fns, 646 of which are private,

1:51 199 vars, 7 macros, 29 atoms

1:52 that's our stats right now

1:52 dissipate: my god, 646 private functions. that's ridiculous

1:53 why do you need all that privacy?

1:53 noprompt: dissipate: 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.

1:53 seancorfield: like i say, legacy code

1:53 we don't bother now

1:53 amalloy: you still work on dating websites, right seancorfield? privacy should be important, see

1:53 seancorfield: we just haven't gotten around to making them all public... would make our test code cleaner :)

1:54 amalloy: lol... members' privacy is important, our own functions not so much :)

1:54 tolstoy: don't the tests call the public functions, which call the private functions?

1:55 seancorfield: tolstoy: well, that's the issue... we test some private functions... so either we shouldn't test them or they should be public

1:55 dissipate: noprompt, did you know Clojure has a location on Earth? behold: http://what3words.com/*Clojure

1:55 hiredman: dissipate: it's everywhere you want to be

1:55 dissipate: hiredman, no, it's actually in Antarctica

1:55 tolstoy: seancorfield: I use private functions mainly just to keep the implementation details separate: but I guess a comment would work just as well.

1:56 seancorfield: tolstoy: i'm leaning toward all public - you never know when those "implementation" functions will be useful to "client" code

1:57 I haven't written a private function for a few months now... "I got better!" :)

1:57 goldfeld: seancorfield: do you think private functions are a bad thing?

1:57 dissipate: seancorfield, i haven't written a 'goto' statement in 3 days

1:57 seancorfield: I think they're pointless... if they're pure functions they might as well be public

1:57 goldfeld: i tend to think of it as it being the kind of composing which has no real use in being exposed

1:58 tolstoy: seancorfield: Does the distinction between "app" code and "library" factor in to that?

1:58 dissipate: goldfeld, encapsulation comes from OOP. yuck

1:58 goldfeld: wouldn'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?

1:59 dissipate: i like to think in terms of bottom up design, not necessarily encapsulation

1:59 but 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

1:59 amalloy: dissipate: 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

1:59 goldfeld: otherwise it's just confusing for users

2:00 dissipate: goldfeld, can't you pick which symbols get imported into the namespace by default?

2:00 tolstoy: goldfeld: that's kinda my take on it.

2:01 hiredman: goldfeld: as a consumer of many libraries, it sucks when people who write libraries make it harder to use what I want from them

2:01 goldfeld: bottom 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

2:01 hiredman: private is just silly

2:02 dissipate: amalloy, well, it's there now. http://what3words.com/*Clojure

2:02 goldfeld: hiredman: 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

2:03 hiredman: goldfeld: the correct thing to do if you care about users is to write docs

2:03 seancorfield: tolstoy: no, I see no point in private functions anywhere now

2:03 hiredman: goldfeld: marking things as private or not has no effect on my ability to read code

2:04 seancorfield: use namespaces to separate API from implementation

2:04 hiredman: I just mentally check the "this was written by one of *those* people" box in my head

2:04 and go on reading

2:04 goldfeld: hiredman: i agree that docs are the ideal case

2:04 seancorfield: ++hiredman

2:04 dissipate: seancorfield, that's what i just said!

2:04 seancorfield, why can't you just set the default imports?

2:05 seancorfield: we're all in violent agreement then :)

2:05 tolstoy: Now everytime I type defn- I know I'm sinking another level in hell.

2:05 dissipate: seancorfield, except for the location of Clojure

2:05 goldfeld: in among namespaces and docs i think i can agree with you guys as well

2:05 hiredman: goldfeld: private isn't even a "less than ideal case" it is just being silly

2:05 seancorfield: don't worry tolstoy I've written my fair share of defn- but that will change :)

2:06 dissipate: tolstoy, why is that?

2:06 tolstoy: seancorfield: I think the use/not-use of it is such a trivial issue that it's not even worth calling it "silly".

2:06 goldfeld: you may have spurred a change within now

2:06 actually 'defn-' is pretty bad to start with

2:06 tolstoy: dissipate: I was just being snarky about how foolish one can be made to feel using a language feature. ;)

2:06 goldfeld: i find it barely readable

2:07 especially when quickly scanning code

2:07 hiredman: clojurebot: private is <reply> not even once

2:07 clojurebot: Ok.

2:07 seancorfield: defn- only exists because it's hard to get rid of.. but there's no def- and clojure/core has repeatedly rejected calls for it

2:07 tolstoy: Yep.

2:07 goldfeld: within me*

2:07 tolstoy: But I likes it. ;)

2:07 goldfeld: yes, i have used only defn ^:private

2:08 out of spite

2:08 tolstoy: I also like a few ;;------------- mixed in there. ;)

2:08 Nyyx: I cant discard arguments in lambda macros can I? (fn [_] (do-whatever)) -> #((do-whatever))?

2:08 dissipate: tolstoy, defn is not a builtin

2:09 seancorfield: Nyyx: not sure what you're asking there...?

2:09 tolstoy: I was refactoring someone else's all-public namespace, and couldn't tell which functions were used externally.

2:09 Nyyx: the former takes an argument and does nothing with it

2:09 but the latter doesn't take an argument

2:09 and I need it to, but throw it away

2:10 goldfeld: tolstoy: yes, i still think there might be use for the lone private function

2:10 seancorfield: Er, so why use #(..) instead of (fn [_] ..) then?

2:10 Nyyx: I know I can do it with a higher order function but that's not what I want

2:10 lazy to type fn [.. ]

2:10 >.>

2:10 tolstoy: dissipate: You mean it's a macro built out of primitives?

2:11 goldfeld: i 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

2:11 seancorfield: Nyyx: that makes no sense :) use the correct construct!

2:12 dissipate: tolstoy, that's correct. i believe 'def' is a builtin but not 'defn'

2:12 seancorfield: goldfeld: no use to who? the user of the library may well find it very useful

2:13 dissipate: tolstoy, but its not a macro. the builtins are not macros. they are just part of the language, the core constructs.

2:13 tolstoy: dissipate: 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.

2:13 goldfeld: seancorfild: 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

2:13 acidental*

2:13 seancorfield: (defn f [..] ..) is just (def f (fn [..] ..))

2:13 tolstoy: Doesn't defn also add metadata where def doesn't, or something?

2:13 seancorfield: hiredman: help me out here :)

2:14 tolstoy: Like defn also has metadata about the argument list or something?

2:14 seancorfield: tolstoy: sure, yes, but that's not a big deal - i was just simplifying

2:14 hiredman: goldfeld: the end user is in far better place to decided is useful than you are

2:14 seancorfield: ,(source defn)

2:14 clojurebot: Source not found\n

2:14 seancorfield: bah!

2:14 dissipate: tolstoy, oh sorry, i meant defn is a macro, but builtins are not macros.

2:14 tolstoy: seancorfield: Yep. ;)

2:14 goldfeld: seancorfield: 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

2:15 tolstoy: dissipate: Yep, I get what you're saying.

2:15 seancorfield: goldfeld: right so use two namespaces - the DSL and the implemntation - if it's important to keep them separate

2:15 hiredman: you are hiding laziless (not wanting to deal with the friction of a new namespace) behind supposed concern over users cognitive load

2:16 how do you measure that cognitive load? have you done studies showing it was a problem?

2:16 seancorfield: s/laziless/laziness/ i assume?

2:16 hiredman: yes

2:16 goldfeld: i

2:16 my bigger concern is not my lazyness

2:16 hiredman: users are not babies to be coddled

2:16 goldfeld: it's the users' lazyness

2:17 hiredman: nor do they need to be

2:17 seancorfield: groovy takes the position of "who are you protecting things from?" and i (now) agree

2:17 clojure allows you to circumvent privacy with #'

2:18 privacy is an illusion

2:18 goldfeld: hiredman: 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

2:18 tolstoy: Which doesn't mean it's not a useful one.... (but I'm not a library writer).

2:19 hiredman: private 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

2:19 goldfeld: let's call it open source marketing

2:19 Nyyx: seancorfield: I'm from haskell I'm lazy by default

2:19 hiredman: an

2:19 dissipate: hiredman, ever heard of Programmer Anarchy?

2:19 hiredman: dissipate: yes

2:20 dissipate: hiredman, under Programmer Anarchy everything gets ripped out all the time. :P 2 months is a dog's age for an app.

2:20 seancorfield: hiredman: I (now) agree that private is a ridiculous conceit from OOP that makes no real sense in real world programming

2:20 hiredman: seancorfield: welcome to the foldl

2:20 seancorfield: Nyyx: sorry about Haskell :)

2:20 goldfeld: i do agree separate namespaces for different levels of the dsl is the better solution

2:21 hiredman: ~rimshot

2:21 clojurebot: Badum, *tish*

2:21 seancorfield: foldl or foldr? :)

2:21 goldfeld: but i'd still take private fns over a dump of public functions all on the same namespace and no api docs

2:21 seancorfield: API docs = docstrings

2:22 there's no separation

2:22 goldfeld: wait, wait

2:22 but then how do you provide an easy referenc index of what's the 'dsl'?

2:22 i mean, if you don't have separate namespaces for different levels

2:22 tolstoy: goldfeld: And when you're writing an app, it seems overkill to create deeper levels to put implementation details. Balance and proportion!

2:23 goldfeld: i think there's docstrings and then there's 'general usage' summary

2:23 two parts of the documentation

2:24 seancorfield: goldfeld: I didn't say I supported a single namepsace for the whole library

2:24 goldfeld: the usage part points towards what the idea of the dsl is

2:24 seancorfield: you can have docstring on ns too...

2:24 dissipate: tolstoy, your app shouldn't be more than 200 LOC

2:25 goldfeld: seancorfield: i agree that's the way to go

2:25 hiredman: or, you know, a readme

2:26 goldfeld: in any case i'm now discussing just hypothetical non-best-case scenarios of library design, so i guess it's time i stop

2:26 hiredman: I always just end up reading the code anyway

2:27 seancorfield: weirdly 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

2:27 dissipate: hiredman, what do you think of writing apps that were just tiny services that you string together? it's the Unix way.

2:28 goldfeld: you guys did convince me to start just putting my private functions in 'lower level' namespaces, making them public

2:28 so thank you

2:29 hiredman: dissipate: *shrug* osx is the only widely used unix microkernel I am aware of

2:29 goldfeld: suddenly the defn- vs defn ^:private in my head's been made irrelevant

2:29 seancorfield: I would say "public by default" unless you have a really good reason to make something private - and remember it can still be acceessed anyway

2:33 goldfeld: i think you actually won me over when you started attacking OOP

2:34 maxthoursie: wait, is there a difference between defn- and ^:private ?

2:34 dosen't read that way to me: (list* `defn (with-meta name (assoc (meta name) :private true)) decls)

2:35 seancorfield: maxthoursie: er... did someone say they were different?

2:36 goldfeld: oh let me attack OOP some more :)

2:36 maxthoursie: maybe not, I got the impression by goldfeld prev comment

2:37 goldfeld: maxthoursie: the vs. was entirely around style and readability

2:37 seancorfield: I 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! :)

2:37 maxthoursie: goldfeld: ah, ok, false alarm then :)

2:37 seancorfield: (defn ^:private...) and (def ^:private...) are more consistent... (defn- ...) is the odd one out...

2:38 goldfeld: seancorfield: so what were your FP beginnings?

2:38 seancorfield: SASL and Miranda - and a PhD in functional language design and implementation :)

2:39 goldfeld: it's funny back when i got into engineering they taught me Fortran, meanwhile compsci taught Haskell and everyone found that somehow weirder than mine

2:39 maxthoursie: cool, that's two languages I hadn't heard about

2:40 goldfeld: that was around 8 ago

2:40 years*

2:40 seancorfield: I 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...

2:40 goldfeld: seancorfield: way ahead of the curve

2:41 seancorfield: for my PhD I developed my own language - SURE - on top of Peter Henderson's LispKit

2:41 goldfeld: maxthoursie: for a moment i thought you were talking about the languages i mentioned

2:42 seancorfield: my final year project at university was to write an APL interpreter

2:42 maxthoursie: :)

2:43 goldfeld: i 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

2:43 ugh, missed some I's

2:43 seancorfield: I went back to Emacs in September 2011 after about a 20 year gap...

2:44 I 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 :)

2:45 goldfeld: too cool

2:45 i have stolen many a trick LightTable uses for node+cljs as well node-webkit

2:45 doing a pet project on top of it with cljs as well

2:46 so the open sourcing was a real boon for me

2:46 amalloy: emacs 17.x! i didn't know there were any versions before 22

2:47 (wouldn't that be great? the next project i release will go straight to version 19)

2:47 goldfeld: if you consider how long it's been around, you could say they were relatively conservative with major release numbers

2:49 tolstoy: Aren't the version numbers really 0.22, 0.23? When did they give up the leading 0?

2:49 seancorfield: emacs 15.34 appeared in 1985

2:49 dissipate: seancorfield, why do so many sneer at light table, or don't consider it a 'real' IDE?

2:50 seancorfield: no idea... i switched over from emacs when 0.6.0 appeared and use it full-time every day for all my editing

2:51 rurumate: I 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

2:51 goldfeld: the only reason i don't switch for my clojure editing is evil-mode

2:51 dissipate: seancorfield, wow, interesting...

2:51 goldfeld: though maybe if i really learn paredit i could do without evil

2:52 and lt's vim mode might be sufficient

2:52 seancorfield: ok, bedtime here... chat tomorrow

2:52 goldfeld: is LightTable even supposed to be a 'real IDE'? isn't more of an editor on steroids?

2:53 i guess i oughta be going too

2:53 rurumate: or maybe locking

2:53 dissipate: seancorfield, what do you think of Forward Inc.'s claim that they don't write apps more than a few hundred LOC?

2:53 systemfault: goldfeld: I think it was "marketed" as an IDE.

2:54 rurumate: the interesting thing is that there is no "see also" here: http://clojuredocs.org/clojure_core/clojure.core/locking

2:54 systemfault: goldfeld: 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."

2:55 dissipate: systemfault, but has it lived up to the hype?

2:59 rurumate: talking of emacs, emacs' clojure mode syntax highlighter apparently doesn't highlight 'ignore next form' comment block a la #_(won't-run) property

2:59 *properly

3:01 dissipate: rurumate, how well does emacs highlight heredocs?

3:02 rurumate: I dunno, not at all? Is theere

3:02 *is there a reason?

3:04 or should I rather ask these things in #emacs

3:05 dissipate: rurumate, just curious. a lot of editors do not highlight them properly

3:05 rurumate: there'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>

4:15 ericdwhite: I'm looking for an idiomatic of validating inputs in clojure. Does anyone have some examples/

4:15 'idiomatic way of ...'

4:17 clgv: ericdwhite: you mean parameters passed to functions?

4:18 ericdwhite: yes, I have data coming in from a JSON API in a map and I want to do some validations before passing that on

4:19 clgv: I was doing it inside of let [] deconstructions but it felt wrong

4:22 clgv: ericdwhite: 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

4:22 ericdwhite: for checking the content schema of maps there are several libs

4:27 ericdwhite: clgv: I just found this post where they use core.match : https://groups.google.com/forum/#!topic/clojure/9W_4COx5Bhc

4:32 clgv: ericdwhite: well, core.match is for advanced branching logic and not really intended for parameter validations

4:34 ericdwhite: :clvv: yes, but I thought the approach of switching based on a validation returning a map of errors was good

4:35 clgv: (match (validate my-map) and then [{:errors errors} original-map] (handle-errors) or [_ original-map] (save original-map)))

4:38 clgv: ericdwhite: I would not try to pull in every clojure library there is, if I were you ;)

4:39 ericdwhite: if you really get benefits from core.match go for it but the sample above suggests that pure clojure with destructuring suffices

4:45 ericdwhite: clgv: 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.

5:03 riz_: hi

5:03 I'm confused about an atom statement

5:03 would anybody be willing to explain?

5:25 noto2: riz_, sure

5:25 riz_: thanks here's the line:

5:26 TEttinger: if it's over a line or two use a pastebin

5:26 riz_: (def app-state (atom {:testimonials (shuffle testimonials)}))

5:26 what exactly is this doing?

5:27 here's the link:

5:27 http://danielsz.github.io/2014/02/28/The-pleasantness-of-Om/

5:27 It says the testimonials are stored in a Vector of maps

5:28 TEttinger: it'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

5:29 riz_: ok makes sense

5:29 what about the next line:

5:30 (defn transition [state] (om/transact! state :testimonials #(if (seq (pop %)) (pop %) (shuffle testimonials))))

5:30 TEttinger: gotta say I haven't used Om and am not familiar with its API

5:31 I'm guessing that's something like swap! in normal clojure.core

5:32 riz_: 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 ?

5:33 TEttinger: (doc pop)

5:33 clojurebot: "([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."

5:34 riz_: so if seq would fail if there were no items left?

5:34 TEttinger: yes

5:34 if there's one element

5:34 riz_: oh ok

5:35 so it seems it's doing pop % whether it's seq or not

5:35 TEttinger: and it pops it, (seq (pop [1337])) will return nil

5:35 pop isn't mutating the list though

5:36 and that's an if block

5:36 (if (seq (pop %)) (pop %) (shuffle testimonials))

5:37 that says, if there would be at least an element left after popping from the arg %, then return (pop %), else return (shuffle testimonials)

5:38 riz_: ohhhhh

5:39 that makes perfect sense :)

5:39 TEttinger: hooray!

5:39 riz_: yeah i for some reason was thinking it was modifying the sequence - how imperative of me!

5:40 thanks very much for explaining :)

5:40 TEttinger: no problem :)

5:40 riz_: btw, do you know about the google summer of code?

5:40 TEttinger: sorta yes

5:41 summer seems a ways off still

5:42 riz_: the applications start in march though

5:42 do you use Light Table?

5:43 TEttinger: yes, sometimes. also nightcode

5:43 riz_: do you write clojure for a living ?

5:44 TEttinger: nope, hobbyist

5:44 riz_: I'm wondering what sort of tools people use for large scale clojure development

5:44 in order to debug, test, etc

5:44 TEttinger: prismatic is doing it, not sure how

5:44 but they're definitely large-scale clojure

5:46 riz_: oh never heard of their app

5:46 TEttinger: their libs are used more I think haha

5:46 but they are quality libs

5:46 riz_: oh are they open source?

5:46 TEttinger: some

5:46 https://github.com/Prismatic/hiphip is one

5:47 riz_: what do you like about nightcode?

5:47 TEttinger: https://github.com/Prismatic/dommy also gets a lot of attention

5:48 uh, 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)

5:50 I better get some rest. good luck with the Om stuff!

5:50 riz_: thanks :)

5:50 i'll try out night code

5:54 lnostdal: hi 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(?)

5:57 clgv: lnostdal: the indirection is always there for normal clojure functions

5:57 lnostdal: clgv: ok, thanks!

5:57 clgv: lnostdal: otherwise you could not redefine functions and use them immediately without recompiling all the other dependent namespaces

5:58 lnostdal: yep

5:58 clgv: afair that indirection could be improved by invoke dynamic of java 7

6:34 jaley: can 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

6:38 spelufo: Is it in your PATH?

6:39 do `echo $PATH` on the command line. I am on Ubuntu 12.04 and I have it in /usr/lib/jvm/java-7-oracle/bin

6:41 actually, 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

6:43 hyPiRion: `sudo update-alternatives --config java` ?

6:46 dsrx: d'oh.. just learned C-c C-c does the same thing as C-M-x (and is way easier to type)

7:10 clgv: (inc clojure.test.check)

7:10 lazybot: ⇒ 1

7:24 jaley: re: 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)

7:45 john2x: ping bitemyapp

7:53 random123: Could someone suggest a website where I could learn closure like learnstreet etc

8:10 clgv: Is it possible to manually add line metadata to the code generated in a macro?

8:11 such that I'll get it displayed on an exception?

8:40 BalkyDwarf: random123: 4clojure.org

8:44 kathy: Hola!

8:45 Pupeno: Hola kathy, como estas?

8:45 kathy: Hola, bien y tu?

8:45 Pupeno: Bien bien, gracias.

8:45 kathy: Me alegra!

8:46 Pupeno: bbl

8:47 kathy: Que?

8:47 Holaaa

8:48 Pupeno: kathy: en un rato vengo.

8:49 kathy: Ok!

9:02 john2x: hi. 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?

9:03 cark: as far as i know, you need to restart it

9:22 gfredericks: john2x: yeah in general (regardless of cider) you have to restart after changing deps

9:22 clgv: is there a macroexpansion function where you can specify which macros should be expanded and the remaining ones are untouched?

9:23 ericdwhite: Ok, 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

9:23 john2x: cark, gfredericks: thanks. coming from vim, it's not so bad with cider. feels like nothing at all.

9:23 ericdwhite: I have put the sample code here: https://www.refheap.com/49553

9:23 gfredericks: clgv: I've thought that would be nice a lot of times

9:23 clgv: gfredericks: yeah. but damn that means you dont know one

9:24 john2x: yeah that would be useful

9:24 gfredericks: ericdwhite: oh no oh no this is the either monad

9:25 every time you end up writing monad code in not-haskell, an angel loses its wings

9:25 clgv: haha

9:25 gfredericks: clgv: you'd want it to work recursively like with macroexpand-all?

9:25 clgv: gfredericks: I thought of patching mexpand-all from tools.macro

9:26 gfredericks: clgv: I was about to mention tools.macro

9:26 clgv: 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

9:26 clgv: oh wait there is something like "protected-symbols" in tools.macro

9:27 gfredericks: yeah?

9:27 clgv: not sure what it does exactly just tracing it through the code

9:27 gfredericks: ericdwhite: lines 15->17 could be cleaned up with ->>

9:28 ericdwhite: and lines 3-4 and 8-9 could use cond->

9:29 ericdwhite: gfredericks: thanks let me give it another pass

9:29 gfredericks: ericdwhite: but the whole thing could be a bit more declarative

9:30 to factor out the common parts you'll get between all validators

9:31 (defn make-validator [pred err-key msg] (fn [input errors] (cond-> errors (not (pred data)) (assoc err-key msg))))

9:31 ^ for example

9:32 ericdwhite: ok let me try that

9:32 gfredericks: s/data/input/

9:34 clgv: gfredericks: monkeypatching tools.macro and using the protected symbol map does not seem to work :(

9:36 gfredericks: huh; it's dynamic, but private

9:36 veird

9:36 weird

9:37 oh the comment on line 44 suggests it's for locals

9:38 I wonder if it's only for symbol-macros?

9:39 looks like it should work as best I can tell

9:42 clgv: gfredericks: ah it works. I forgot to add both symbol and resolved symbol

9:57 harr errors are much easier to spot when a "when" is a "when" instead of expanded to an "if"

10:01 I remember that there was a clojure editor component announced as library on the mailing list. how was it called?

10:12 ericdwhite: gfredericks: Do you mind have another look at: ttps://www.refheap.com/49563

10:13 s/have/having/

11:01 clgv: ericdwhite: but as I said, there are libraries for this task, clj-schema, prismatic/schema ...

11:03 ericdwhite: clgv: thanks, I'm just trying to get my basic clojure to a decent level. I will take a look at those libraries.

11:04 for example is it a good idea to use -> the way I did inside the let statement, or is that a totally bad idea.

11:14 benmoss: does anyone know if there's a way to use Schema with multi methods?

11:14 * stranger9811 Anybody can tell me how to apply for clojure organisation in GSOC

11:15 * stranger9811 with whom I can discuss my project idea.

11:15 benmoss: i mean aside from just calling validate, there's no macro for defining the defmethod and the schema for the arguments

11:17 tgoossens: I've not been following clojure news for 3 months. What did I miss ? :)

11:18 seangrove: benmoss: That's a good question, I hadn't looked into that at all

11:18 gtrak: wrap the multimethod in another defn.

11:19 but I feel to lazy to do that for protocols, too

11:19 benmoss: gtrak: like triple dispatch?

11:19 gtrak: too*

11:19 yea

11:19 benmoss: yeah, that could work

11:19 gtrak: another level of indirection solves everything

11:19 seangrove: Or actually, in th defmulti, have a {:pre } check in your method you're using to dispatch

11:19 That's essentially what gtrak suggests, just without an extra fn

11:20 benmoss: thats a good idea, i forgot that was a possibility

11:28 seangrove: I think this weekend I need to write some posts about Omchaya and the design decisions

11:28 This "auto-reload state" thing is amazing

11:29 `cbp: omchaya?

11:29 oh i see

11:30 bbloom: seangrove: what's the auto-reload state thing?

11:30 seangrove: bbloom: https://www.dropbox.com/s/vdnjnmfb5b120gk/om_save_restore.mov

11:31 * bbloom loves living in the future

11:31 seangrove: Hit 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:31 bbloom: which is really the past

11:31 that is super nice

11:31 good job

11:32 seangrove: bbloom: ~4 lines of code

11:32 When your world is serializable, everything is easier

11:32 bbloom: seangrove: true story.

11:33 seangrove: bbloom: 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:33 Beyond just good patterns people can learn from, I'd really like to get to actualy reuse/sharing

11:34 bbloom: seangrove: can't you get access to the entire data subtree (violating encapsulation) of all sub components?

11:34 seangrove: ie couldn't you just have a component which wraps the root?

11:35 would be cool to just have a heavily parameterized root component for debugging tools

11:35 seangrove: bbloom: That's a good idea

11:35 So, 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:35 bbloom: if you wanted them, all you need to do is change your app from <MyRoot.../> to <RootWrapper saveload={{true}}><MyRoot...

11:36 would be awesome if that root wrapper had like a floating toolbar too, so you could configure it

11:37 turn 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:37 seangrove: bbloom: 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:37 bbloom: like having a replay slider, state inspecter, etc

11:37 yeah

11:37 seangrove: It's actually probably not too bad

11:38 A tab component, draggable window component, and then let people put in the components they want for their debug toolbar

11:38 bbloom: the naive thing probably works: have them bubble events up to the root debugging component

11:38 don't let them write to storage locally, just have them bubble save/load requests

11:38 then the root component can prefix their state keys to isolate them, etc

11:39 seangrove: bbloom: 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:39 bbloom: i 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:39 seangrove: I really like the multimethod with controller/post-controller approach

11:39 bbloom: seangrove: heh, is this exactly what i suggested around bubblign control events?

11:39 seangrove: Pretty much ;)

11:39 That's how we designed our app, and then how we built Omchaya

11:40 bbloom: perfect.

11:40 really nice work

11:40 brb

11:40 seangrove: Take 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:55 ,(let [x (atom {:a 10 :b [20 30]})] [(identical? x (swap! x identity)) (identical @x @(swap! x identity))])

11:55 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: identical in this context, compiling:(NO_SOURCE_PATH:0:0)>

11:55 seangrove: ,(let [x (atom {:a 10 :b [20 30]})] [(identical? x (swap! x identity)) (identical? @x @(swap! x identity))])

11:55 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.util.concurrent.Future>

11:56 seangrove: ,(let [x (atom {:a 10 :b [20 30]})] [(identical? x (swap! x identity)) (identical? @x (swap! x identity))])

11:56 clojurebot: [false true]

11:56 seangrove: ,(let [x (atom {:a 10 :b [20 30]})] [(= x (swap! x identity)) (= @x (swap! x identity))])

11:56 clojurebot: [false true]

11:56 seangrove: Identity and equality are hard.

12:00 amalloy: seangrove: i don't see what you're trying to demonstrate (or confused about?)

12:00 seangrove: amalloy: Oh, not demonstrating anything, sorry. Just checking some assumptions

12:01 The first check is obviously wrong looking at it now, please disregard ;)

12:05 tgoossens: borkdude, lang geleden :)

12:05 *long time no see

12:06 borkdude: Is there a lib which expose reference types with history as in Datomic? Like (get! some-atom #inst 'an hour ago') ?

12:06 (deref ... #'inst 'an hour ago')

12:07 tgoossens hi

12:07 tgoossens I have been here regularly ;)

12:07 tgoossens: i know

12:07 It's me who has been inactive for a few months in the clojure community

12:07 borkdude: tgoossens actually me 2, but since a few weeks it's getting more active

12:08 tgoossens: New project? Or courses that are starting?

12:08 borkdude: tgoossens I'm not a lecturer anymore, but I have been doing a clojure project, then Java, and then clojure again

12:08 tgoossens: oh

12:09 My 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:09 borkdude: tgoossens I know the feeling, Java drains all your positive energy ;)

12:10 tgoossens: hha

12:11 I should put some more time into my clojure meetup. I'm getting a bit sloppy

12:17 borkdude, did I miss some shocking news in the clojure world?

12:20 borkdude: tgoossens Datomic Pro has a free to use variant

12:20 tgoossens There is a new front end library which I hear a lot about called Om

12:21 tgoossens Maybe Cursive Clojure?

12:21 tgoossens Caribou

12:21 tgoossens Version 1.6 coming soon

12:21 tgoossens I don't know for the rest

12:22 tgoossens Schema and Liberator, but those aren't really new

12:22 tgoossens: hmm a clojure IDE

12:23 borkdude: tgoossens Hoplon is also coo

12:23 l

12:23 tgoossens: :D

12:28 is there already a talk on cursive available somewhere?

12:52 locks: err’body talking about Om :}

13:00 seangrove: Liking our hn job postings more and more each month. Think we're building up a reasonable profile for good engineers.

13:06 wei__: 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:06 seangrove: wei__: text inputs?

13:07 wei__: yeah, so I have three text inputs. they should all update (according to a formula) when you change any of the inputs

13:07 seangrove: wei__: It's slightly tricky, but not horribly so. Can you paste your component and atom code somewhere?

13:08 wei__: sure thing, thx. give me a sec..

13:09 bjorkintosh: 366 in #lisp but 681 in #clojure. where did CL fall short?

13:09 much amaze. very wow.

13:12 RickInAtlanta: bjorkintosh: how do you search by language?

13:12 AimHere: Probably just asks his client for a list of how many people are in each channel

13:12 bjorkintosh: top right in xchat, RickInAtlanta.

13:13 RickInAtlanta: thanks

13:14 isaacbw: common lisp isn't 'in' anymore

13:15 bjorkintosh: naturally :)

13:15 wei__: seangrove: https://gist.github.com/yayitswei/9294380 .. probably horribly un-idiomatic :)

13:15 it also doesn't quite work yet

13:16 pepijn: How do I make a list of distinct elements in core.logic? Like (fresh [a b c d ....] (fd/distinct a b c d....))

13:16 seangrove: wei__: Hrm, I don't use render-state, I'd have to look up what that's for

13:16 How's it different from just om/IRender?

13:17 wei__: it takes a local component state

13:17 which I actually don't need here, hmm

13:18 seangrove: wei__: I don't think changing opts will trigger a re-render

13:19 wei__: shouldn't (swap! app-state ...) trigger a re-render?

13:19 seangrove: wei__: One second, let me see if I can refactor this a bit

13:23 wei__: 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:25 seangrove: wei__: is the label rendered correctly?

13:25 qbg: Why does numeric-input have :value (id state)?

13:25 wei__: yes, the label shows up

13:25 qbg: Shouldn't that be (id input)?

13:26 Also, if you're going to use IRenderState, you should either specify the initial state when using om/build, or also extend IInitState

13:27 wei__: 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:28 seangrove: wei__: https://www.refheap.com/542dc1f51bf05110b74cef51f

13:28 (id state) seems wrong first off

13:28 should probably be (get-in state [:options id]), I think

13:28 qbg: I don't see any reason for local state here

13:28 you want to be using input

13:29 wei__: even if I used :path at the bottom to base the cursor off :options?

13:29 qbg: And handle-numeric-change shouldn't be touching app-state directly

13:29 input is a cursor

13:30 (id state) should be (id input)

13:30 seangrove: wei__: I think you might be right about :path, good point. Happy to hop on a google hangouts to pair. Probably faster

13:31 qbg: and handle-numeric-change should be taking in input and using om/transact!

13:31 wei__: qbg: (id input) does give me the correct initial display

13:32 what's the difference between om/transact! and (swap! app-state ..) ?

13:32 qbg: (swap! app-state assoc-in [:options id] (text->value text)) should most likely be (om/update! input id (text->value text))

13:32 om/transact! operates on a cursor

13:33 and affects what is pointed to by the cursor instead of the whole state

13:33 wei__: will swap! trigger a re-render though?

13:33 qbg: it should

13:34 wei__: seangrove: let me puzzle it out a bit more, will definitely hit you up if I get stuck- really appreciate it

13:35 seangrove: wei__: Definitely. And also check out Omchaya, it's a good reference point.

13:36 bbloom: 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:43 eraserhd: What 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 `cbp: um

13:45 well i use h2 from time to time

13:49 plookn: what's wrong with sqlite?

13:53 pepijn: what the... is this? (core.logic): (( 0 :- (!= ( 1 2))))

13:55 iwo: hey, can anyone help me with a link to the clojure blog where the author makes all their posts as code?

13:55 i 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:56 bbloom: seangrove: i wasn't looking too closely anyway :-P

13:57 seangrove: bbloom: Well, just a nice architecutre

13:57 pepijn: Condensed code: https://www.refheap.com/49699

13:58 I 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:59 iwo: some 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:00 pepijn: The result actually is ((_0 :- (!= (_1 _2))))

14:04 nvm, I remembered something stupid

14:15 kathy1: Hola

14:17 wei__: 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:18 seangrove: wei__: Probably it's operating on a string

14:18 javascript "9" + 1 => "91"

14:18 gfredericks: gtrak: ping

14:19 wei__: it should operate on the result of #(if empty? % 0 (js/parseFloat text))), which I expect to always be numeric

14:20 eraserhd: plookn: 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:21 qbg: Your if expression is also wrong

14:21 It should be (empty? %) instead of empty? % in it

14:22 plookn: eraserhd: have you seen korma? seems pretty good to me. https://github.com/korma/Korma

14:22 seangrove: wei__: qbg is right. (if empty? is always true, and so you just return `text`

14:26 qbg: om.dom/wrap-form-element seems to be doing something weird

14:31 eraserhd: plookn: Maybe I'm old, but I was hoping for something like -lgdbm, and not something SQL-y.

14:31 wei__: (inc qbg)

14:31 lazybot: ⇒ 4

14:31 wei__: (inc seangrove

14:31 )

14:32 oops

14:32 (inc seangrove)

14:32 lazybot: ⇒ 2

14:33 gfredericks: does anybody know under what conditions (compilation, repl, lein details, etc) a compile error would cause just the single line "Subprocess failed" of output?

14:34 seangrove: Out of negative karma at least

14:35 wei__: (dec seangrove)

14:35 lazybot: You want me to leave karma the same? Fine, I will.

14:38 iwo: finally google fu revealed the name, it was John Lawrence Aspden

14:42 qbg: Can anyone else reproduce my Om issue, or see a problem in this code? https://gist.github.com/qbg/9295942

14:52 seangrove: qbg: What do you mean controlled/uncontrolled?

14:53 qbg: http://facebook.github.io/react/docs/forms.html

14:53 In the Gist posted, you shouldn't be able to change the text

14:54 seangrove: qbg: Ah, I see

14:56 qbg: Just as a guess I'd say that dom/input is actually a component with its own :onChange, etc.

14:56 wei__: 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:56 qbg: seangrove: It is. Check out om/wrap-form-element

14:56 *dom that is

14:57 seangrove: qbg: Yeah, looking at it. We use sablono, which I believe skips om/input|textarea, etc.

14:57 wei__: you're not supposed to be able to enter non-numeric characters, but the textbox still changes

14:58 ptcek: Is bidi a feasible alternative to compojure?

14:58 qbg: wei__: I produced that gist above from reducing down your code :)

14:59 wei__: oic :)

14:59 kevinfish: why 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:59 seangrove: Probably good to ask dnolen_ what the idea behind om.dom/input is, how to use it, etc.

14:59 wei__: qbg: it works as expected in the Om tutorial though

14:59 dnolen_: seangrove: it fixes React input for async rendering

15:00 seangrove: The value for om.dom/input is set from local state

15:02 wei__: kevinfish: try upgrading your clojure version?

15:02 also, not sure if contrib is supported anymore

15:02 qbg: yikes, 1.2.0 is pretty old

15:06 dnolen_: Any thoughts on my gist? https://gist.github.com/qbg/9295942

15:07 kevinfish: how do I do the project.clj so it just uses the newest of everything?

15:07 just leave off the string version numbers?

15:08 qbg: kevinfish: I'm not sure you can, and if you could you wouldn't want to anyways

15:09 Since you wouldn't want your project to break just because someone released a new version of <insert library here>

15:11 kevinfish: qbg: k, do old versions ever cease to become available or to work?

15:11 qbg: They shouldn't

15:12 at least for releases

15:12 dnolen_: 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:13 even if the value doe not change

15:13 qbg: using React input does not work at all, the cursor will move

15:13 I mean the input cursor (not Om cursors)

15:13 wei__: 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:16 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:17 awalker: undocumented (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:17 dnolen_: wei__: update! just defers to transact! and yes

15:17 kevinfish: wei__: k, thx, I'll try it

15:19 wei__: 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:20 awalker: I 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:21 boothead: Hi 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:23 bbloom: seangrove: i think that's your cue :-)

15:24 * boothead searches seangrove finds omchaya... Thanks bbloom :-)

15:25 kevinfish: wei__: k, thx. One at a time is the key :)

15:25 bbloom: boothead: in summary. Om, although young, is the best thing out there for client-side app dev, bar none

15:26 wei__: *if you know Clojure

15:26 bbloom: wei__: true.

15:26 boothead: bbloom, for what reasons? how about reagent?

15:26 bbloom: i haven't looked at reagent closely, but let me clarify that cljs+react = best thing

15:26 boothead: wei__, oh dear. however the backend is written in Haskell so how hard can it be ?:-)

15:27 bbloom: boothead: ha. answer is: much easier, once you un-type-poison your brain

15:27 boothead: bbloom, thems fightin words! ;-)

15:28 dnolen_: boothead: Reagent is very cool, Om is a bit more opinionated with respect to state management

15:29 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:29 boothead: dnolen_, as I haskeller I approve of opinionated state management (obviously) what are om's opinions?

15:30 dnolen_: boothead: as much as possible state transitions transition the entire application

15:30 app state -> function -> new app state

15:30 boothead: also 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:30 bbloom: ~reader

15:30 clojurebot: reader is http://news.ycombinator.com/item

15:30 bbloom: boo

15:30 clojurebot: forget reader

15:30 clojurebot: Gabh mo leithscéal?

15:31 dnolen_: boothead: well that a different problem, learning the language, https://github.com/swannodette/lt-cljs-tutorial

15:31 bbloom: clojurebot: reader is http://clojure.org/reader

15:31 clojurebot: Roger.

15:31 bbloom: boothead: that doc page will explain all the symbols, there are not many

15:32 boothead: 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:32 boothead: dnolen_, ah yes I came across that - very useful, thank you!

15:33 amalloy: clojurebot: forget reader |is| http://news.ycombinator.com/item

15:33 boothead: bbloom, "just" a macroin the same way that a monad is "just" a moniod in the category of endofunctors? :-)

15:33 clojurebot: I forgot that reader is http://news.ycombinator.com/item

15:34 bbloom: boothead: 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:34 boothead: if you can understand cut/paste, you can understand macros enough to use them

15:34 boothead: actually dnolen_ state -> function -> new state isn't that dissimilar from how the backend works

15:38 bbloom, 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:38 qbg: yes

15:38 bbloom: boothead: use macro expand to confirm:

15:38 ,(macroexpand '(-> 1 str clojure.string/trim))

15:38 clojurebot: (clojure.string/trim (str 1))

15:38 boothead: so why what's the trade off in writing it the other way?

15:38 ah nice!

15:39 and what's the "," at the beginning for?

15:39 bbloom: boothead: similar use cases as $ in haskell: convenience of notation, evaluation order, etc

15:39 the , is a directive to clojurebot

15:39 ,5

15:39 clojurebot: 5

15:39 bbloom: 5

15:39 &"is for lazybot"

15:39 lazybot: ⇒ "is for lazybot"

15:39 bbloom: in clojure, commas are normally just whitespace

15:39 boothead: ah cool thanks!

15:39 bbloom: and & is just an ordinary symbol, although it is generally used for "rest args" notation in many places

15:41 boothead: is there a recursive version of macroexpand? I get (clojure.string/trim (clojure.core/-> 1 str)) in the repl

15:41 bbloom: ,(clojure.walk/macroexpand-all '(-> x y z w))

15:41 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk>

15:42 bbloom: ,(require 'clojure.walk)

15:42 clojurebot: nil

15:42 bbloom: ,(clojure.walk/macroexpand-all '(-> x y z w))

15:42 clojurebot: (w (z (y x)))

15:42 firefaux: is there a function like map-invert which keeps all duplicates?

15:43 so instead of (map-invert {:a 1 :b 1}) => {1 :a}, I want (map-invert* {:a 1 :b 1}) => {1 #{:a :b}}

15:44 amalloy: &((fn map-invert [m] (apply merge-with into (for [[k v] m] [v #{k}]))) {:a 1 :b 1})

15:44 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry

15:44 amalloy: &((fn map-invert [m] (apply merge-with into (for [[k v] m] {v #{k}}))) {:a 1 :b 1})

15:44 lazybot: ⇒ {1 #{:a :b}}

15:44 gfredericks: ,(macroexpand-1 '(-> x y z w))

15:44 clojurebot: (w (z (y x)))

15:45 gfredericks: boothead: that less helpful output is better in 1.6

15:45 boothead: dnolen_, 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:45 gfredericks: &(macroexpand-1 '(-> x y z w))

15:45 lazybot: ⇒ (clojure.core/-> (clojure.core/-> x y) z w)

15:45 boothead: thanks bbloom!

15:46 dnolen_: boothead: well that's how Om works

15:46 firefaux: amalloy: that's wonderful

15:46 amalloy: now I'll have to figure out exactly how it works

15:46 dnolen_: 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:47 boothead: dnolen_, the cursor right?

15:47 dnolen_: boothead: yep

15:47 boothead: do 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:48 dnolen_: boothead: people already using it anger

15:48 * gfredericks stares at Compiler.java

15:49 piranha: what'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:49 bbloom: dnolen_: 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:50 dnolen_: bbloom: yep

15:50 boothead: my 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:51 dnolen_: bbloom: and it's selectors over something useful, your components, not the stupid DOM

15:51 bbloom: dnolen_: true fucking story

15:52 gfredericks: boothead: I think cemerick's survey says that the proportion of industrial use is rising significantly

15:53 boothead: gfredericks, i hope so! I'm doing my bit to help (hopefully) http://www.meetup.com/London-Start-Up-Functional-Programmers/

15:56 dnolen_: piranha: a lot of people seem to pair CLJS with Ring

16:00 piranha: dnolen_: hm, ok

16:15 gfredericks: I think it might be unwise to deal heavily with the

16:15 clojure compiler without a java IDE

16:35 bacon1989: Hi, is there a simple way to do an outer join between two sequences?

16:36 like I have a range 1 to 10, I want to get a list of [[1 1] [1 2] ... [10 10]]

16:36 I feel like i'm not approaching this correctly, and it seems like a rather simple problem

16:37 gyim: like this? (for [i (range 1 11) j (range 1 11)] [i j])

16:38 bacon1989: haha yes

16:38 I didn't know for was like a list comprehension

16:38 thank you, that should get me in the right direction

16:38 much appreciated

16:38 gyim: (y) you're welcome

16:44 TimMc: gfredericks: 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:51 pepijn: dnolen_: guess what. someone is paying me to play with core.logic :D

16:55 goldfeld: dnolen_: does om + pedestal make any sense to you?

17:04 Rich_Morin: I'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:12 gfredericks: TimMc: just working on tickets; CLJ-1347

17:13 bbloom: Rich_Morin: i hesitate to mention it... but just your comment & title sounds to me like XPath/XQuery/etc

17:14 but generally, i've felt the urge for a clojure-ish tree selector syntax before

17:14 although i can't recall the use cases now, i do recall that ultimately i needed domain-specific semantics

17:16 Rich_Morin: My page mentions XPath, as well as the Unix shell. I also mention the Rails (etc) router syntax.

17:18 Clearly, 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:18 TimMc: gfredericks: 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:18 justin_smith: http://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:18 bbloom: Rich_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:18 justin_smith: it's someone else's SO question, but I think it is exposing a bug in the compiler / implementation

17:19 bacon1989: question, 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:19 justin_smith: bacon1989: thanks to chunking it could read a bit further than the element asked for

17:19 but never the whole thing

17:19 bbloom: Rich_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:19 Rich_Morin: bbloom: almost - to use globbing, you want to start with a tree (or at least a DAG).

17:20 bacon1989: ok thanks, i'll see how well it performs

17:20 bbloom: Rich_Morin: sure, i don't believe in cyclic values :-P

17:21 TimMc: gfredericks: I'll dig into it more at work, but I figured I'd ask in case you already knew. :-)

17:21 justin_smith: bacon1989: if an expensive op is producing the lazyseq I think there are options for preventing chunking

17:22 Rich_Morin: bbloom: So, for example, get-in could be extended with some form of wildcard syntax.

17:22 bbloom: Rich_Morin: yup

17:23 Rich_Morin: be careful though to include an escaping syntax too then :-)

17:23 (query-in a-map [:foo wild :bar])

17:23 vs: (query-in a-map [:foo (literal wild) :bar])

17:24 seems like a pretty straightforward thing to build

17:25 the-kenny: Is there a nicer way than having to run three instances of lein for cljsbuild, cljx, and repl?

17:29 Rich_Morin: bbloom: My Ruby version takes about 200 LOC, including lots of comments.

17:29 the-kenny: ah, there's lein-pdo.

17:29 bbloom: Rich_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:31 Rich_Morin: The code is shown in http://wiki.cfcl.com/Projects/Ruby/Tree_Globbing#Implementation

17:44 AmnesiousFunes: Style question: what is the canonical formatting for cond pred/expr pairs for large or nested forms?

17:44 bbloom: AmnesiousFunes: weeee

17:44 AmnesiousFunes: nobody seems to agree :-P

17:45 AmnesiousFunes: bbloom: Will I be considered a heretic if I align the exprs vertically?

17:45 bbloom: AmnesiousFunes: nope

17:46 AmnesiousFunes: bbloom: Excellent, thank you.

17:48 seangrove: bbloom: What's the idea behind :instrument in Om?

17:49 Asking you since you seem to get it and I haven't seen anything written about it so far

17:59 gfredericks: TimMc: do you set *compile-files* or whatever that var is?

17:59 TimMc: do you get other class files associated with the namespace as a result?

18:23 bbloom: seangrove: it's an aspect-oriented programming feature, where some function is applied to all components

18:23 seangrove: 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:24 seangrove: bbloom: Interesting. And there's a way to selectively apply the instrumentation functions?

18:24 That would be fantastic

18:25 bbloom: seangrove: well, no instrument function is just the identity function

18:25 well, three argument identity

18:26 you're just intercepting every call to build

18:26 you can run any predicate you want to decide what to do

18:26 devn: wow, purnam looks awesome

18:27 seangrove: Hrm, 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:28 bbloom: seangrove: sure, you can filter by cursor or whatever or whatever, then just inject whatever you like

18:29 seangrove: bbloom: got it, sounds pretty nice

18:29 bbloom: In the meantime, have you seen React DevTools with Om? Pretty nice until Om-specific tools popup

18:30 bbloom: seangrove: haven't tired them, got a video?

18:30 seangrove: bbloom: I'll send a screenshot in just a second

18:30 bbloom: oh i guess i can try it on fb

18:30 seangrove: bbloom: Current version doesn't work with Om, just got the patches into master yesterday

18:30 bbloom: seangrove: awesome

18:31 trying it on fb now

18:32 that's freaking awesome

18:34 seangrove: 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:34 re-parenting is possible, but would require a more sophisticated id generation scheme

18:35 gotta go, cya

18:36 seangrove: bbloom: When you get back http://dl.dropbox.com/u/412963/Screenshots/d4.png

18:47 TimMc: gfredericks: 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:48 seangrove: dnolen_: How can we get (om/build-all to give a unique key to each component?

18:48 Nyyx: anyway to use map as a bimap?

18:49 dnolen_: seangrove: map over elements to build + some key generator

18:49 petehunt: seangrove: dnolen_: react generates one

18:49 this._rootNodeId i believe

18:49 seangrove: dnolen_: map om/build rather than (om/build-all ?

18:49 dnolen_: seangrove: yes

18:50 petehunt: you may need to add this._mountDepth in there too

18:50 seangrove: dnolen_: Alright, got it. Won't that by default mean that build-all is going to hurt performance?

18:50 dnolen_: seangrove: no, it generates a key for you.

18:50 seangrove: but it's just based on index

18:50 seangrove: which will screw you if you do insertions etc

18:51 bbloom: I don't follow the instrument thing

18:51 seangrove: dnolen_: Looking at it in the RDT, I don't see any react-keys associated with the components

18:51 dnolen_: bbloom: though we'll see how useful instrument is in general case

18:51 bbloom: I'm starting to identify some cool possibilities

18:52 gotta run

18:53 seangrove: dnolen_: 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:56 Nyyx: bimaps?

18:58 gfredericks: TimMc: "files" refers to the target of compilation, not the source

18:58 TimMc: (source gen-class) makes it obvious that gen-class is a noop when *compile-files* is falsy

19:15 muhoo: what the idiomatic way in om and core.async to check the current application state at every iteration?

19:15 just deref the atom?

19:15 it felt to me like that'd be considered un-om-like.

19:16 seangrove: muhoo: What are you checking?

19:16 muhoo: Worth checking out https://github.com/sgrove/omchaya/raw/master/docs/resources/omchaya_flow.png

19:17 muhoo: seangrove: thanks, what you are working on there is extremely exciting

19:17 seangrove: muhoo: We have 3 swaps! in our Omchaya, and 2 derefs

19:18 muhoo: what i'm checking is a :run? flag in the state

19:18 seangrove: muhoo: 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:18 muhoo: But when/where?

19:19 muhoo: seangrove: https://www.refheap.com/49856

19:19 it's just a toy, i'm learning om

19:19 seangrove: dnolen_: Having trouble getting wrap-form-element to return a class that handles displayName properly

19:20 muhoo: 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:22 muhoo: om 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:23 seangrove: muhoo: Same here. It's all mainly enabled by react, but Om forces an extra layer of good decisions

19:24 muhoo: it was a natural convergence. just watched peter hunt's talk last night.

19:24 immutability, composability, intelligent handling of state, what a natural fit for clojure(script)

19:25 seangrove: dnolen_: Never mind, it's sablono copying/pasting Om code

19:26 I love hiccup, but Sablono is definitely harshing my frontend a bit

19:26 muhoo: seangrove: 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:26 gtrak: what 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:27 seangrove: muhoo: 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:29 muhoo: seangrove: sweet, thanks.

19:29 seangrove: muhoo: 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:29 riz_: hi, can somebody explain to me benefit of using "recur" as opposed to just calling the function itself to do recursion?

19:30 amalloy: riz_: stack overflows

19:30 seangrove: I 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:30 Nyyx: riz_: try doing it without a recur but make sure you loop 10000 times

19:30 seangrove: Kandan is a perfect app to get that setup initially

19:31 Nyyx: and then do it with recur

19:31 riz_: ok

19:31 seangrove: riz_: 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:39 dnolen_: 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:39 dnolen_: Specifically this needs to be modified https://github.com/r0man/sablono/blob/master/src/sablono/interpreter.cljx#L11

19:40 riz_: ok thanks guys

19:40 i think it makes sense

19:40 greg`: i just watched rich hickeys talk on the functional database really liking the datomic stuff

19:40 ruzu: rich can get me to like anything

19:41 greg`: lol he really is an intelligent and charasmatic character

19:41 gtrak: the compiled client.js is just empty..

19:41 greg`: im quite new to clojure has anyone here used datomic?

19:45 muhoo: greg`: many have. best to just ask your question.

19:46 i've used it, and enjoyed it a lot

19:46 bjorkintosh: greg`, it came from prolog, don't forget.

19:47 greg`: what do you mean y tha bjorkintosh

19:47 i gueess i just want to ask do you think it would scale

19:47 its it like some driver that can connect to more tradiitional db's itstelf or is it a ful dbms

19:48 bjorkintosh: scale? do you have a scaled userbase already?

19:48 if not, don't worry about that, and just learn it well.

19:48 muhoo: it scales ridiculously when you use the amazon db backend :-)

19:49 only 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:50 greg`: 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:50 bjorkintosh: datalog.

19:51 muhoo: greg`: 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:05 gtrak: I think I fixed austin for cljs master :-)

20:06 now I'm getting my nice tooling in a brepl.

20:17 kopasetik:

20:17 oops

20:17 gtrak: ~guards

20:17 clojurebot: SEIZE HIM!

20:18 kopasetik: *runs in the other direction*

20:18 gtrak: now I just have to learn Om..

20:19 dsrx: om works so well with repl development

20:19 like, absurdly well

20:19 kopasetik: currently taking a ruby on rails class, but i look forward to really getting my hands dirty with clojure a few months later

20:20 so far i've just set up my dev environment (leiningen, etc)

20:21 gtrak: dsrx: what's the latest and greatest resource on it? Been looking at omchaya.

20:21 kopasetik: has anyone read "joy of clojure?"

20:21 gtrak: kopasetik: great book

20:21 TimMc: gfredericks: Hmm! I don't get what you mean about targets of compilation, but I'll take another look at gen-class' source.

20:22 gtrak: kopasetik: Not a beginner's book though.

20:22 took me a while to get through it, but it was good stuff.

20:22 seangrove: Jesus, is Omchaya already dated?

20:22 * seangrove shakes his head

20:22 kopasetik: gtrak: great to know

20:23 gtrak: seangrove: I mean.. I can read it and see how it works, np.

20:23 I started to go through the git commits to try and grasp how it got built.

20:23 seangrove: gtrak: Yeah, haven't been goot about the commits

20:24 gtrak: I'm just impatient and ADD, in general.

20:24 seangrove: Most of the patterns were lifted from our production app

20:24 gtrak: wondering if there's any elucidating blog posts since the last time I looked.

20:24 kopasetik: gtrak: is there a clojure book that you'd recommend to beginners?

20:24 gtrak: I heard 'Clojure Programming' is good.

20:25 kopasetik: gtrak: cool

20:25 Has anyone here tried coding w/ clojure for android products?

20:26 gtrak: kopasetik: last I could tell it wasn't production-grade.

20:28 kopasetik: gtrak: so it doesn't make sense to use clojure to make android apps, huh?

20:28 gtrak: been meaning to try cljs with phonegap again :-).

20:29 kopasetik: cool

20:30 anything i can do to minimize the amount of java i'd have to code... :-P

20:30 gtrak: it's relatively easy to get a REPL running in phonegap, took me about an hour to figure it out.

20:31 but basically you have to have something serve the dev-html so cross-origin isn't an issue.

20:31 I suppose you could also do it with jsonp.

20:31 seangrove: $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:31 lazybot: Message saved.

20:32 kopasetik: gtrak: ok

20:34 gtrak: about how much of your clojure coding is repl-based?

20:34 gtrak: all of it

20:35 kopasetik: wow. that sounds awesome.

20:35 gtrak: as opposed to running unit-tests from cmd-line?

20:35 or what?

20:36 one of the unfortunate things about clojure is it's too slow to do anything else :-

20:36 :-)

20:37 kopasetik: yeah, vs jumping back and forth between a text editor and the command line

20:37 well, that's one of the consistent drawbacks of functional programming, isn't it?

20:37 it's powerful and expressive, but it runs slowly right?

20:38 gtrak: it runs fast actually, it just starts up slow. Almost bearable in small projects.

20:38 when I was playing around with cljs last, I did the lein-cljsbuild and refresh the web page thing a lot.

20:38 RickInAtlanta: it is the jvm that is slow

20:38 on startup

20:38 gtrak: but I hope to stay on the repl now.

20:39 RickInAtlanta: gtrak: connecting to a browswer in LightTable is pretty cool. ctrl+enter and the dom updates

20:39 gtrak: neat

20:40 light table's just calling the cljs compiler itself?

20:40 RickInAtlanta: the Om tutorial is a good demonstration of that https://github.com/swannodette/om/wiki/Basic-Tutorial

20:41 whether 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:41 dsrx: gtrak: if you're using cider or whatever you can just C-c C-c the appropriate expressions too

20:41 gtrak: yea, that's what I used to do and hope to avoid.

20:41 RickInAtlanta: compiling is really fast

20:41 dsrx: or C-c C-k and send the whole namespace over

20:42 locks: the Om tut is very nice

20:42 dsrx: s/namespace/file

20:45 RickInAtlanta: to compile clojure code, you need java 6 right? Need jdk, or just jre?

20:46 AimHere: Just the runtime

20:47 ruzu: 6? bah!

20:47 RickInAtlanta: thx

20:47 gtrak: 7's a bit faster, using 8 myself.

20:47 AimHere: leiningen is hugely recommended if you're doing anything but anything in clojure

20:52 ruzu: leiningen's monopoly is unhealthy :P

20:53 locks: ruzu: time to make an alternative

20:53 gtrak: it's a natural monopoly

20:54 there used to be 'cake'

20:55 there's always maven..

20:56 justin_smith: compared 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:01 ruzu: sure, there are benefits to One True Way :)

21:01 amalloy: if you enjoy pain, ruzu, you can always manage your classpath and invoke java manually

21:06 seangrove: Alright, 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:08 gtrak: hrm.. is it a known issue of austin that the env doesn't stick around after a refresh?

21:09 I guess that makes sense, but it is le-suck.

21:10 seems like it could dump the analyzer state to the client-js on a refresh.

21:16 seangrove: gtrak: That's a feature in Omchaya as of yeserday

21:17 gtrak: how'd ya do that?

21:17 seangrove: Optional persisting/restoring of state

21:17 gtrak: I want the actual repl state.

21:17 not just app state :-)

21:17 seangrove: Hrm... for example?

21:18 gtrak: like... if I refresh the webpage, it throws out the JS environment, which throws out all loaded cljs and closure code.

21:18 dsrx: gtrak: really?

21:18 that doesn't seem right

21:18 gtrak: maybe 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:19 seangrove: gtrak: I see, I usually have the two things be the same

21:19 gtrak: which two things?

21:21 seangrove: Loaded 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:21 gtrak: ah, yea. I'm not using the FS at all for this, except source.

21:21 seems like it could be made to work.

21:21 then I'd have a smooth clojure-like experience :-)

21:22 dsrx: gtrak: piggieback does not manage the compiler env

21:23 gtrak: how do you figure?

21:23 I rely on that for my auto-complete impl.

21:24 dsrx: piggieback holds onto an IJavaScriptEnv record that manages the compiler/analyzer state, but that's all created + implemented in austin

21:24 seangrove: gtrak: As an aside, the auto-complete can't query the js-runtime about available symbols, right?

21:24 gtrak: seangrove: nope, it doesn't.

21:25 seangrove: Definitely 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:25 gtrak: here we go:https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/middleware/util/cljs.clj#L17

21:25 it's in the nrepl session.

21:25 seangrove: I can live without the JS env for now.

21:26 seangrove: gtrak: Oh yes, definitely far better than the current state

21:26 dsrx: gtrak: yeah, as I said piggieback holds onto a repl-env, but it doesn't manipulate its state or anything like that

21:27 gtrak: piggieback implements the nrepl load-file eval stuff.

21:27 austin uses piggieback as a backend.

21:27 dsrx: gtrak: it implements the nrepl front end for the load-file

21:27 but actually loading the file into the repl-env is delegated to the IJavaScriptEnv

21:28 gtrak: dsrx: that's the JS

21:29 now, 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:30 RickInAtlanta: does anyone know if there is a "table of contents" page for Clojure From the Ground Up

21:36 gtrak: dsrx: hrm, trying to figure out where the analysis result gets swapped into the compiler-env again.

21:39 piggieback tacks it on to the rhino env at least, I think the cljs compiler itself updates it. checking austin now.

21:41 aha!

21:41 same key: https://github.com/cemerick/austin/blob/master/src/clj/cemerick/austin.clj#L399

21:44 dsrx: I 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:44 oops

21:44 gtrak: so, 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:45 then the browser could load that instead of a blank slate.

21:45 dsrx: gtrak: 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:45 gtrak: yea

21:45 exactly

21:45 dsrx: ahhh, nice

21:46 I'm not terribly familiar with the analyzer internals, but that seems reasonable to me

21:46 gtrak: well, 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:46 IE I think transitive deps don't get reloaded into the browser.

21:47 might be an easier fix to just clear the compiler state, but not as fun :-)

21:49 I'll have to go bother Chas later.

21:58 seangrove: $mail ddellacosta check out https://github.com/r0man/sablono/issues/18

21:58 lazybot: Message saved.

22:02 bbloom: seangrove: so i'm not sure if i understand sablono.... other than the #js literals for react props is less than ideal

22:03 if i understand correctly, sablono only works for dom nodes, but not components, right?

22:03 seangrove: bbloom: Exactly, which I'd like to see rectified eventually, but haven't got to it yet

22:04 Ideally 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:04 bbloom: seangrove: 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:05 seangrove: bbloom: I'm partial to hiccup syntax, but I've been waffling about that as well.

22:05 bbloom: seangrove: well hiccup mainly makes sense b/c the entire tree must be reified and manipulatable

22:05 seangrove: however, with the react model, you intentionally want encapsulation

22:06 further, the react internals won't regenerate, or rehydrate, or traverse, or even consider, the subtree if it's not necessary

22:06 seangrove: bbloom: IO

22:06 bbloom: so splicing, is only really useful for the children sequence at most

22:06 seangrove: Whoops. I like the idea of having data structures that may be transformed very easily.

22:07 bbloom: but in that case, i rather maps than the hiccup syntax

22:07 seangrove: bbloom: 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:08 I don't know if it's all worth it though

22:08 bbloom: seangrove: sure, but hiccup is syntax, which is annoying b/c you have to detect & deal with the optional map value

22:08 seangrove: Still feeling it all out

22:08 True

22:08 bbloom: my original design (prior to react and looong before om) was a rewriting model

22:09 seangrove: Rather than {:attrs .. :content ... :etc ..}

22:09 bbloom: where type/props/children/state/etc == just one map merged as appropriate

22:10 bah, i can't explain it here

22:10 one of these days i'll have to finish that project

22:10 i could probably make it work great directly on react w/o the loads of other stuff i had planned on....

22:10 maybe i'll just make a proof of concept & let somebody else do the rest of the work :-P

22:10 seangrove: bbloom: Make a note to tell me when you're out here, I'm very curious to explore this space right now

22:12 bbloom: seangrove: let me see if i can get a bit of the idea out...

22:12 component instances would be maps and they'd be rewritten according to some simple rules

22:12 seangrove: What kind of rewrites, and what kind of rules?

22:13 bbloom: trying to think up a good example

22:13 seangrove: Like a macro-expansion process?

22:13 bbloom: yes

22:13 justin_smith: I'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:13 bbloom: seangrove: so an example would be the "prototype" property, which would be reverse-map-merge

22:13 justin_smith: looks like it is leaking, mainly leaking char, but also leaking object, byte etc.

22:13 seangrove: bbloom: I has a very similar idea sketched out as well

22:14 justin_smith: eventually it dies with a heap error, as that SO post notes

22:14 bbloom: {:prototype :button :text "hello"} could expand to {:template (fn ...) :text "hello"}

22:14 and then templates would be called given the rest of the object

22:15 so the button template might be (fn [{:keys [text]} {:html/element "div" :css/margin "5px" :children {:html/element "span" :html/content text}})

22:15 for example

22:16 prototypes 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:16 then the result would be shallow, just like in react, and the result would get rendered

22:17 (fn [{:keys [text]}] {:html/element "div" :css/margin "5px" :children [{:html/element "span" :html/content text}]}) ; fixed braces

22:17 my plan was for this exact model to support stuff besides :html/element, like say :canvas/shape

22:17 firefaux: does anybody know where clojure.contrib/core has moved to now?

22:18 bbloom: if you had a :canvas/shape that wasn't inside an :html/canvas, then a rewrite rule could easily insert one :-)

22:18 seangrove: bbloom: Yeah, I was thinking about approaching this with multimethods, but this seems sensible

22:18 bbloom: seangrove: i actually have this mostly sorta working with java2d rendering and no optimizations (ie it just rerenders the full view 60fps)

22:18 in that context, i had to tackle layout and everything else too

22:19 seangrove: i'll show you how it all works at clojure/west

22:19 basically, it's WPF without databinding lol

22:20 firefaux: ooh, I just found that core.incubator has most if not all of the contrib/core functions

22:20 seangrove: bbloom: Sounds great. I think there may (possibly!) be some value to using this model to generate mobile web views from a xib package

22:20 Or vice-versa

22:20 bbloom: seangrove: yeah, my plan was to support arbitrary display backends. just swap out the prototypes/templates

22:20 seangrove: Exactly

22:20 bbloom: seangrove: i have a java2d render and a hiccup renderer

22:21 jvm clj side. was trying to get the model right first

22:21 then react came out and i stopped working on it lol

22:21 i 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:22 seangrove: bbloom: Well, I think they more or less got it on the desktop, but certainly not in the browser

22:22 And maybe not even in the desktop... but certainly closer there :P

22:22 bbloom: seangrove: you kidding? the desktop frameworks aren't anywhere near react

22:23 seangrove: at least in terms of semantics

22:23 seangrove: bbloom: Thinking about tooling

22:23 bbloom: tooling & functionality, oh yeah, desktop is much better

22:23 seangrove: bbloom: In Xcode you drag mockup components around, declaratively configure them, and get a ton of mileage

22:23 bbloom: yeah, but it's a sham

22:23 seangrove: The description is compiled down into the actual implementation in a separate step

22:23 bbloom: it's very superficial declarativeness

22:24 seangrove: Sure, but it's far better than what we've had in the browser!

22:24 bbloom: yeah, browser quality & perf sucks

22:24 and until react, the semantics were even worse

22:24 seangrove: Well, and also semantics

22:24 Heh, yes, exactly

22:25 bbloom: in game engines, they get it

22:25 seangrove: Which is mind-boggling

22:25 bbloom: google for "IMGUI"

22:25 i was in here blabbing about IMGUI for months last year lol

22:25 seangrove: There isn't much reuse in the game world's take, though

22:25 bbloom: nah, 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:26 take a look at Unity's ui toolkit

22:26 i hear it's got it's own sorts of flaws & whatnot, but overall it's very react-like

22:26 although it relies on the perf of gpus to be a lot less clever in it's optimization

22:26 seangrove: bbloom: Until major license engines like Unreal/Unity/etc. I should say, heh

22:27 bbloom: unity'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:27 you basically just render a subview in to a texture and composite

22:27 which is much nicer than dealing with the dom :-P

22:27 seangrove: bbloom: Make sense

22:27 bbloom: I'm pretty excited for all of the stupid work that's about to go away for web devs

22:27 bbloom: indeed

22:28 90% of the work "engineers" do these days is glorified desktop publishing at best

22:28 seangrove: I feel like I want to go around rebuilding people's ui's - "Look, isn't this so simple now? And fun?"

22:28 bbloom: heh

22:28 seangrove: We'll see when that feeling wears off, but for now it's great.

22:29 bbloom: 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:30 bbloom: seangrove: i'm confident you can do it!

22:30 * bbloom concludes his pep talk

22:30 * seangrove is pepped

22:30 seangrove: Oh man, insta-state-reload is so lovely

22:31 bbloom: true story

23:15 quizdr: re

23:15 ruzu: mix

23:15 dsrx: pl

23:16 quizdr: if 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:24 goldfeld: quizdr: if you need to alter a single path down the nesting, update-in may suffice

23:33 seangrove: bbloom: 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:33 quizdr: goldfeld thanks i'll look into that

23:34 bbloom: seangrove: it's much much easier if all widgets have the same, known height. start there

23:34 seangrove: bbloom: Yup

23:34 bbloom: seangrove: i don't think you need to worry about blank placeholders, just absolute position inside a way oversized container and use scroll always

23:34 css scroll-y: always, i mean

23:35 start w/ a non-virtualizing stack panel, which should be easier & show me the code & i'll help you make it virtualizing

23:35 seangrove: bbloom: Alright, will do

23:57 dfsai: I'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:58 ryantm: dfsai, seems only more readable when reading backwards.

23:58 ambrosebs: dfsai: for one we generally have better tools to manage parens, so we don't need to be as defensive

23:59 ryantm: dfsai, Also, you don't mess up the parens if you use something like Paredit

Logging service provided by n01se.net