#clojure log - Mar 02 2014

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

0:02 dfsai: ryantm: checking out paredit. WOW.

0:03 amalloy: dfsai: yeah, if you don't have something like paredit the parens can be pretty cumbersome. but paredit is like...amazing

0:05 koreth__: Though the vim one takes a bit of getting used to. (Not an Emacs guy so I can't vouch for the original.) It still trips me up pretty often but saves more time than it costs, so definitely worth checking out.

0:05 ambrosebs: FWIW I use vim with rainbow parens.

0:05 dsrx: dfsai: paredit is awesome

0:07 and yeah, rainbow parens + a good indenter can help you to unpack the structure of a form a bit too

0:08 dfsai: do you guys use rainbow parens exlusively over syntax highlighting (or are they even in opposition to each other?)?

0:08 ambrosebs: I use both

0:08 dsrx: they complement each other very nicely

0:08 dfsai: at the same time? Like, in one given moment?

0:08 dsrx: another option is to use a mode that highlights matching parens

0:08 like, as your cursor is on them

0:10 bob2: highly recommend keeping http://www.emacswiki.org/emacs/PareditCheatsheet open, and every time paredit frustrates you, read it to figure out how to do the thing you want

0:10 took a few days for me to go from hating it to enabling it in other non-lisp modes

0:11 justin_smith: also, with paredit, C-w and C-q are your "cheat codes" to do the things paredit tries to prevent

0:11 sometimes it is just easier to use those (especially when first learning paredit)

0:12 `cbp`: C-q?

0:12 bob2: and sometimes C-u

0:12 justin_smith: it literally inserts the next character

0:13 Cq-) will insert ) regardless of paredit rules

0:13 for example

0:13 I use C-q " to break up strings in paredit (there is likely a more elegant solution, but it only comes up so often for me)

0:15 amalloy: i mean, it's convenient to have an escape hatch like C-q (quoted insert, adds the following character regardless of keybindings) or C-u C-d (delete next character regardless of keybindings). otoh, if you find yourself in a situation where you want those, it's often better to check the cheatsheet to see if there's a better answer

0:15 dfsai: Does paredit come with emacs 24?

0:15 amalloy: i have to use those escape hatches like...once a month

0:15 dfsai: bundled? Or do you get it from marmalade?

0:15 amalloy: dfsai: i think just marmalade

0:15 `cbp`: justin_smith: M-S

0:17 justin_smith: another good trick: C-u M-x paredit-mode will turn on paredit, even if the buffer is not currently balanced

0:18 amalloy: that's like an anti-trick, justin_smith. better to clean up the buffer than have paredit confused

0:18 justin_smith: amalloy: repl buffer

0:18 the output of the repl can confuse paredit

0:18 amalloy: ehhhhh, i guess. i don't really find it worthwhile to have paredit on in my repl

0:18 but i suppose if you do, you'll want to be able to force it on

0:18 goldfeld: when paredit annoys me, i do evil things to it

0:19 works out well for me

0:19 justin_smith: yeah, I use that, plus the C-q / C-w tricks in order to never have paredit turned off, which big picture is the bigger win

0:19 goldfeld: also bob2: thanks for the cheatsheet link, i really need to deepen my paredit usage

0:20 `cbp`: i rarely type on my repl. I use keybindings that send expressions to it =)

0:20 goldfeld: amalloy: at first i didn't have it in the repl, but once i got used to having it there too, i couldn't go back

0:20 amalloy: goldfeld: yeah, i understand that's a valid workflow used even by people who are not crazy, but i'm with `cbp`

0:26 justin_smith: when I type in my repl, I then have the persistent repl history

0:26 it's useful for remembering things I tried out in the past (that have some validity between projects)

0:28 seangrove: Hrm, it seems like onScroll isn't working quite right through Om

0:30 noprompt: seangrove: what are you doing with onScroll?

0:30 seangrove: noprompt: Trying to build a StackPanel component

0:31 I need to be able to scroll events to know what sub-components are in the view currently though

0:31 noprompt: StackPanel?

0:31 seangrove: http://msdn.microsoft.com/en-us/library/cc294551.aspx

0:32 It works in the javascript, I'm not sure what I'm doing wrong in the cljs though

0:33 noprompt: seangrove: are you listening for onscroll in the component?

0:34 seangrove: noprompt: Listening on *everything* at this point ;) https://www.refheap.com/d3191167e441a1369dc3aa231

0:34 I would expect to see "SPV Scroll" in the console when scrolling through the overflow on the div

0:34 If I grab the element in js and listen, it works

0:36 Uhg, is there a way in chrome to switch between sourcemaps and javascript? Source maps are getting in my way at this point

0:36 (I don't want to disable them entirely though, just want to be able to toggle back and forth)

0:37 bbloom: seangrove: you only need onscroll for virtualizing. have you got non-virtualizing working yet?

0:38 seangrove: bbloom: I'm not sure what non-virtualized stackpanel is, other than a div with a fixed height and overflow-y: scroll;

0:38 That renders subcomponents, obviously

0:38 bbloom: seangrove: yeah, the non-virtualizing stack panel renders all children and sets their style property to absolute positions

0:38 it just does layout, not culling

0:39 seangrove: Ah, I see, ok, hold on, will do that

0:39 bbloom: onscroll probably doesn't work via delegation b/c it's too noisey

0:39 noisy*

0:39 seangrove: bbloom: It's supposed to work, if you look in #react

0:39 bbloom: oh yeah, it totally SHOULD work, i'm just saying not if you're trying to catch all events w/o explicitly registering for it

0:39 looking at your code, i see that's not the case

0:40 seangrove: bbloom: Wondering if I hit an Om bug. I'll take care of the positioning first though

0:40 bbloom: yup

0:40 seangrove: noprompt: Any chance you could try to get an onScroll event working on your side?

0:41 noprompt: seangrove: i'm in the middle of patching a secretary bug.

0:41 seangrove: noprompt: No worries, just thought if you were in ankha already ;)

0:41 noprompt: seangrove: and working on a sass->garden in ruby.

0:42 seangrove: noprompt: That's a strange project... migrating your legacy stuff?

0:43 noprompt: seangrove: it's not about legacy; it's about portability. there's a lot of good sass code out there that can be migrated to garden easily by hooking in to the Sass AST and emitting EDN instead of sass.

0:45 seangrove: it's not perfect and won't work in every case but it will work in several of them.

0:45 seangrove: noprompt: That's very clever actually. Really like the idea

0:45 noprompt: $foo: 1px => (def $foo "1px)

0:46 a {b: c; d {e: f}} => ["a" {:b "c"} ["d" {:e "f"}]]

0:47 it's just a pain in the ass because i have to implement to_edn for a bunch of node types.

0:48 dsrx: noprompt: neat, got a migration story for functions/mixins? ;)

0:48 noprompt: dsrx: i'm covering the low hanging fruit first before adventuring in to that territory.

0:48 dsrx: mixins/functions will likely be the last node types i look at.

0:49 again my goal is to get at least 60-80% code generation. if the other 20-40% have to be filled in by hand that's worth it to me.

0:50 gtrak: seems like I might be able to get the compiled files, but not the evals.

0:50 re: cljs

0:50 dsrx: noprompt: is the ast you're using the one that's made after mixin/functions are evaluated/expanded?

0:51 noprompt: it's definitely a weekend project.

0:51 dsrx: yes. all that stuff is available in the sass parse tree.

0:52 dsrx: essentially i'm working with the code just before it's emitted as css.

0:52 dsrx: ah, got it. is there some kind of marker on those nodes indicating which function/mixin generated them?

0:53 noprompt: dsrx: i'm still exploring: https://github.com/nex3/sass/tree/stable/lib/sass/tree

0:53 the cool thing is i'm learning a bunch about the sass internals.

0:54 not that it matters alot.

0:54 seangrove: Hrm, can I not do (dom/div nil (repeatedly 50 #(dom/div nil "example"))) /

0:54 noprompt: seangrove: btw, i'm always down to drop everything for a pairing session. ;)

0:54 seangrove: I guess I'm confused about raw om syntax

0:55 noprompt: Definitely, we'll have to find time for it sometime!

0:55 noprompt: seangrove: i think i ran in to something like that while working w/ ankha.

0:55 seangrove: it's weird. now that i pair everyday of the week i'm kind of addicted to it.

0:56 seangrove: I can do (apply dom/div (concat [nil] (repeatedly 50 #(dom/div nil "example"))))

0:56 noprompt: seangrove: well 5/7 days of the week. :)

0:56 seangrove: I guess that's kind of what I want...

0:56 noprompt: I like pairing, but probably not that much

0:57 noprompt: seangrove: at first it was tough and somedays you really need to let people know you want to work alone for a bit.

0:57 bbloom: i've found pairing to only really be valuable when i have shit i don't feel like doing

0:57 takes 2 people to maintain focus when you'd otherwise slack off on your own :-P

0:58 ruzu: and if the other person feels the same, time to start tripling

0:58 noprompt: the nice thing about pairing is a lot of the stupid mistakes you'd make your pair catches.

0:58 seangrove: bbloom: For remote teams, it's pretty crucial. Helps spread experience

0:58 bbloom: seangrove: that makes some sense

0:58 noprompt: also bugs that might take hours for one person to spot can be resolved quicker w/ two eyes on the code.

0:58 seangrove: that and familiarity w/ the codebase.

0:59 seangrove: bbloom: But the answer to that is "try not to have remote teams"

0:59 bbloom: seangrove: i did 3 months remote where i was the senior engineer... it was really tough

0:59 noprompt: seangrove: i wish i could agree but considering that i live in a place where i'm pretty much the only clj/cljs programmer for another 300 miles it's a godsend.

0:59 bbloom: seangrove: hipchat helps, ghangouts helps, but ultimately, a flight was the best thing for team building

1:00 noprompt: i won't move to san francisco because the cost of living is retarded.

1:00 plus i don't like big cities.

1:00 seangrove: noprompt: I'm with bbloom ;)

1:00 It's a tradeoff, certainly

1:00 koreth__: There are cheaper, less city-like places near SF, but "cheaper" is relative (the whole area is ridiculously expensive).

1:00 seangrove: And that's fine, just pick your value points and live with them

1:01 noprompt: You could join bitemyapp in austin, I head good things

1:01 noprompt: fresno is working fine for me and i don't see any reason to leave just because "tech is happening in city x"

1:01 seangrove: A few people I like and think ahve a good balance live out that way

1:01 noprompt: seangrove: i have a kid on they way, can't do it. :(*

1:01 seangrove: fresno?

1:01 wat?

1:02 i doubt it. everyone here is either a php/python/ruby dev and functional programming is "too X" excuse to get in to.

1:02 i nearly shit my pants when i heard there was an erlang programmer in town.

1:03 seangrove: noprompt: Ah, no Austin. Fresno's fine too. But just have to realize the limitations that come with it, like less likelihood of bumping into clojure devs :)

1:03 noprompt: seangrove: for a person like me it's great. :)

1:04 seangrove: noprompt: Then that's awesome :)

1:04 noprompt: seangrove: why did bitemyapp bail for austin though?

1:05 seangrove: noprompt: He felt it was more his style than SF for a few reasons

1:05 noprompt: seangrove: i talked to him last night but didn't ask.

1:05 seangrove: he's a nice guy, but the dude is totally misunderstood.

1:06 seangrove: noprompt: Yeah, he definitely comes off better in person. I enjoy drinking with him.

1:07 noprompt: seangrove: never got the chance. :(

1:07 seangrove: i was hoping to see him in march.

1:07 err this month.

1:07 seangrove: noprompt: I'm sure there'll be chances in the future, heh

1:08 bob2: hm, midje mode is a bit bizarre

1:12 ddellacosta: seangrove, noprompt: funny to hear you talking about bitemyapp...sounds like he really hated SF when I talked to him

1:12 I have to drop him a line

1:13 noprompt: ddellacosta: i can only handle that city in small doses.

1:13 ddellacosta: noprompt: yeah, I'm thinking of heading back to North America myself and got to figure out where I'm going to end up

1:13 noprompt: SF seems...unappealling, which is sad since there is so much awesome stuff going on there in tech

1:14 *unappealing

1:14 noprompt: ddellacosta: i'd vote for a small town near natural beauty but not so isolated you'd go nuts.

1:14 ddellacosta: noprompt: yeah, as I get older that seems more and more appealing. I think that was in bitemyapp's mind too

1:14 noprompt: ddellacosta: imho, big cities are overrated. small town folk are generally more "human" from my experience.

1:15 seangrove: bbloom: Ok, that's a working non-virtualized StackPanel https://www.refheap.com/71d4dd6181a8316ed2bf087b1

1:15 noprompt: ddellacosta: there's plenty of land. ;)

1:15 ddellacosta: noprompt: I dunno, I have a mixed opinion of that. Growing up in a small town put me off the small-town attitude in many ways. But it is true that small-town folks tend to be more family-like, in sense

1:16 seangrove: noprompt: Heh, not to paint with too broad a brush, I'm sure

1:16 noprompt: ddellacosta: i guess it's all about what you want to be around everyday. do you want a big back yard with a blue sky over your head, or tiny space in concrete jungle.

1:17 seangrove: i try not too which i why i suffixed that statement w/ "from my experience"

1:17 bbloom: seangrove: O_o so many require statements :-p

1:17 noprompt: seangrove: i've met awesome people in big cities too.

1:18 ddellacosta: noprompt: well, to be fair, you should compare "big back yard with blue sky..." with "amazing variety of cultural resources, diverse group of people (potentially), amazing food, and concentration of industry"

1:18 seangrove: bbloom: Oh, just pulling in my existing stuff to populate the stack panel

1:18 bbloom: seangrove: hehe, ok

1:18 ddellacosta: noprompt: the trade off is the small space, yes--but it is all about tradeoffs. Much like building software...heh

1:18 seangrove: bbloom: Ignore them, it just needs om.dom and om.core

1:19 bbloom: seangrove: yeah, you've also got some non-general cruft in here, like the activities stuff

1:19 noprompt: ddellacosta: those are great things for sure. i dunno i've lived in a few different countries and in a big city and at the end of the day i could really care less.

1:19 seangrove: bbloom: One second, I'll pull that out so it's passed in

1:19 ddellacosta: noprompt: yeah, I don't mean to claim one is better than the other, don't get me wrong.

1:20 noprompt: ddellacosta: as long as i have access to clean water, good food, and ample time for my hobbies, family, and dogs everything else is just sugar.

1:20 :0

1:20 :)

1:20 i'm a pretty simple dude.

1:20 ddellacosta: noprompt: you are really reminding me of the things bitemyapp was saying. ;-)

1:20 noprompt: ddellacosta: i blame the drugs.

1:20 haha

1:20 ddellacosta: noprompt: haha

1:21 noprompt: ddellacosta: i mean you live in japan though right?

1:21 ddellacosta: lazyboth says I have messages? Never seen that before

1:21 *lazybot

1:21 noprompt: yep, for now

1:21 noprompt: ddellacosta: i'm not sure what the attitude about gaijin is these days but i'd love to live in aomori.

1:21 my guess is that'd be hard.

1:22 ddellacosta: noprompt: woah, why Aomori? Like the cold and apples? I'm sure that if you could manage their weird dialect you'd be fine.

1:22 noprompt: ... or close to sapporo.

1:22 ddellacosta: that and all the trees. :)

1:22 ddellacosta: noprompt: actually my wife keeps threatening to move us to Hokkaido. I've contemplated that too

1:22 noprompt: ddellacosta: is kanai still the right word?

1:23 ddellacosta: hokkaido looks amazing.

1:23 ddellacosta: everyone wants to go to honshu. :(

1:23 ddellacosta: noprompt: eh, it's kinda old-fashioned. I just use the more formal okusan as I'm progressive that way...haha

1:24 noprompt: ddellacosta: and i guess shujin is out too huh? haha!

1:24 ddellacosta: noprompt: yeah, we went snowboarding yesterday and one of our friends lived in Hokkaido and was raving about how easy it was to go to the mountain

1:24 noprompt: naw, that's fine. ;-)

1:24 noprompt: lol

1:24 doesn't that approximate to "master"?

1:24 sorry my japanese is bad. :(

1:24 ddellacosta: noprompt: it all depends on who you're talking to, and why. My wife usually calls me "danna" when talking to others

1:25 noprompt: and actually never uses "go-shujin" or anything. Mostly she just calls me Dave though.

1:25 noprompt: don't worry, I'm surprised you know so much!

1:27 so, what is up with messages + lazybot?

1:28 ah, from seangrove. Thanks! Didn't know you could send messages like that, neat

1:28 seangrove: bbloom: I got your general right here https://www.refheap.com/943df98afaf0877fc3aa277a6

1:29 noprompt: ddellacosta: i studied japanese for a few years. i have tons of japanes lp's from the 70's. bit of a collector.

1:29 ddellacosta: noprompt: oh, nice.

1:30 seangrove: bbloom: Pretty speedy as is, actually.

1:30 noprompt: deadghost: i always wanted to go but never had the money. now that i finally do, i've got a kid on the way. :(

1:30 ddellacosta: ^

1:30 deadghost: sorry :P

1:31 seangrove: bbloom: Now, curious how you would extend this to be virtualized in a composable way - a VirtualizedStackPanel component that sits on top of it, transfers the props it receives to the child StackPanel, does the calculations, and filters what it passes to the StackPanel to render?

1:31 ddellacosta: deadghost: bring your kid! I guess after a year or so...

1:32 noprompt: ddellacosta: i think you meant that for me. i accidentally mis-tabbed :|

1:33 deadghost: yes, luckily I have no kids

1:33 ddellacosta: deadghost, noprompt: oh, yeah, sorry for the confusion.

1:36 seangrove: hah!

1:36 ddellacosta: seangrove: I have a simple question re: Om/sablono issue--do you see any correlation in whether you use build vs. build-all?

1:37 seangrove: bbloom: Another problem with this is keeping things sized correctly as browser dimensions change

1:37 ddellacosta: Don't use build-all, you can't pass a per-component react key

1:37 * noprompt never uses build-all

1:37 noprompt: sablono is awesome :)

1:38 ddellacosta: seangrove: okay, I think this is coming clear...one sec

1:38 * noprompt playing test wack-a-mole

1:38 noprompt: gah! almost got this bug fixed.

1:40 ddellacosta: seangrove: when you say per-component, do you mean per-instance of component?

1:41 seangrove: since build-all calls build, you should have no problem passing keys/react-keys into build

1:43 seangrove: ddellacosta: I don't see react-keys in here at all.. https://github.com/swannodette/om/blob/master/src/om/core.cljs

1:43 ddellacosta: Ah, yes, I meant per-instance

1:44 ddellacosta: seangrove: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L527 https://github.com/swannodette/om/blob/master/src/om/core.cljs#L560-L562

1:44 seangrove: ddellacosta: But how do you pass that via build-all

1:45 ddellacosta: seangrove: you can pass a third arg into build-all which is the map of options: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L589-L591

1:46 seangrove: ddellacosta: ? The map is static though

1:46 (build-all my-com {} {:react-key "com-1"})

1:46 err, (build-all my-com [{} {}] {:react-key "com-1"})

1:46 Won't all the instances of my-com get :react-key "com-1" ?

1:47 They're siblings, so they need to have unique keys

1:47 noprompt: lol marilyn mason...

1:47 ddellacosta: seangrove: why can't you give them distinct keys? I mean, I'm only advocating for using this if you need a collection of items rendered. Otherwise use build itself

1:48 noprompt: s/mas/mans/

1:48 seangrove: ddellacosta: I guess I'm missing how each instances gets a unique

1:48 key

1:49 ddellacosta: Each my-com gets its own cursor/data, but the opts-map is the same for all of them

1:49 bob2: if I'm writing a command line tool, and would like a couple of different commands, what's the best path to go down? symlinks + examining argv[0]? multiple Main classes + sh wrappers?

1:50 ddellacosta: seangrove: But, you can change it yourself--I thought that was the point?

1:50 seangrove: ddellacosta: change it where?

1:50 ddellacosta: seangrove: it can be a value in what you pass into build-all, which you could pull from your data, for example

1:51 seangrove: ddellacosta: Can you post a gist?

1:51 ddellacosta: seangrove: yeah, let me hack something up

1:51 seangrove: Worth hashing out

1:51 ddellacosta: one sec

1:51 yah

1:58 seangrove: Jesus christ, I can't believe how annoying positioning is in browsers

1:58 Can't wait to fix this and not have to worry about it again

2:02 noprompt: (inc seangrove)

2:02 lazybot: β‡’ 3

2:09 ddellacosta: seangrove: I've figured it all out. Your issue has nothing to do with sablono, I don't believe: https://www.refheap.com/49985

2:10 er, I *do* believe

2:10 * ddellacosta makes English fail

2:10 ddellacosta: ah, let me try it with "raw" Om to be sure

2:10 seangrove: ddellacosta: I'll check it with the React Devtools in a few minutes

2:11 ddellacosta: seangrove: k

2:11 seangrove: They're pretty nice, looking forward to the latest changes to get deployed for both

2:13 ddellacosta: seangrove: which do you mean, sorry?

2:13 seangrove: ddellacosta: https://dl.dropboxusercontent.com/u/412963/screenshots/d5.png

2:13 ddellacosta: Notice the tag names

2:15 ddellacosta: seangrove: woah...x-tags? what is this?

2:15 seangrove: ddellacosta: https://github.com/facebook/react-devtools

2:15 Also lets you look at attributes like key, reactKey, onScroll, onClick, children, etc.

2:16 ddellacosta: seangrove: oh, it's mapping the component name?? That is freaking awesome...

2:16 seangrove: Sadly, the names won't work unless you use master react-devtools and master Om. But the attributes work out of the box (though a little bit more messy), and I'm sure both will be pushed live soon

2:16 * ddellacosta goes to download and set it up

2:17 ddellacosta: seangrove: man, this stuff is so freaking cool. I get mini brain explosions every day lately

2:17 noprompt: seangrove, ddellacosta: omfg this is awesome

2:17 ddellacosta: seriously

2:17 seangrove: ddellacosta: Yeah, same here. Wait until we have rich components that we can jsut take and reuse. I've just about finished up with the stack-panel

2:17 noprompt: and it's totally cool w/ cljs?

2:18 seangrove: noprompt: It'll be messy for now unless you're on master for Om and RDT, but it works, yeah

2:20 ddellacosta: brb

2:21 noprompt: pushed secretary v1.0.2

2:22 seangrove: bbloom: Ok, so I've ported our stuff to use this stack-panel, but window resizes need to be handled. Will think on how to do it cleanly

2:24 ddellacosta: noprompt: nice. Been meaning to ping you about secretary actually. Have some use-cases I want to run by you

2:26 seangrove: noprompt: That include my wish-list? :)

2:26 noprompt: ddellacosta: wtr?

2:26 grrr.

2:26 wrt?

2:27 seangrove: yep. it's definitely gonna happen.

2:27 seangrove: Nice!

2:28 ddellacosta: seangrove, noprompt: what is on seangrove's wish list?

2:29 seangrove: ddellacosta: Just this for now https://github.com/gf3/secretary/issues/16

2:29 dsrx: seems like lately #clojure is much more about clojurescript :)

2:29 seangrove: dsrx: They overlap a bit

2:29 dsrx: I'm not complaining

2:29 seangrove: dsrx: You can think of it like late-nigth public radio ;)

2:30 noprompt: seangrove, ddellacosta: basically break everything for v2.0.0. :)

2:30 dsrx: seangrove: haha

2:31 * noprompt really wishes we could have a clojure hangout.

2:31 * seangrove is slightly nervous about letting bbloom talk him into absolute positioning everything

2:31 noprompt: seangrove: so long as there's position relative on the containing element why not?

2:31 seangrove: noprompt: There are two clojure meetups here, a clojure dojo, a clojurescript meetup every month, and I regularly hack with people on random things once a week

2:31 muhoo: i have to say, this is the most fun i've had programming in i cannot remember how long

2:32 noprompt: seangrove: the problem is for folks like me who can't drive 3.5 hours just for an in person hangout.

2:32 seangrove: noprompt: means you need to handle dimensions all the time

2:32 noprompt: Well, there's clojure/west, we'll hangout then

2:32 noprompt: seangrove: yeah, that can be harry, but not too bad.

2:32 seangrove: noprompt: Need to think if that's part of the global ui state, or component-local

2:32 noprompt: seangrove: sure, but the problem is that not everyone everywhere can physically meet or be on IRC, etc.

2:33 for example i brought up a problem w/ dnolen on the mail list about the cljs exists? function

2:33 it's horribly named, but he only queried folks in IRC about it.

2:33 had i know i would have recommended a different name.

2:34 * ddellacosta *sniffs* remembering he can't go to Clojure/West

2:34 noprompt: exists? is an awful name for a function that really should be called supports? or browser-supports?

2:34 seangrove: ddellacosta: Why not?

2:34 noprompt: seangrove: uh, he's in japan dude. :)

2:34 ddellacosta: seangrove: I just can't afford to fly there and get a hotel and take a week off of work

2:34 seangrove: ddellacosta: Heh, fair enough :)

2:35 ddellacosta: seangrove: and pay for the conference, and eat, and etc. Will cost me in excess of $2K

2:35 muhoo: noprompt: you're in fresno?

2:36 dsrx: it seemed like the LA Clojure meetupa all stopped happening as soon as I joined the meetup.com group :\

2:38 seangrove: dsrx: Push for another meetup, or organize it yourself. People tend to come when given a chance :)

2:39 noprompt: muhoo: yeah lol

2:39 muhoo: dsrx: there are quite a few active clojure folks in LA. see if you can drag them to a meetup. maybe volunteer to present something, or find someone to present

2:39 noprompt: i still think an online meetup would be a good idea.

2:39 dsrx: yeah, I know a couple companies here that use it, like factual

2:40 in fact, they organized all the previous meetups it looks like

2:40 noprompt: if people are willing to physically go to a meetup i don't see why they wouldn't be open to it virtually...

2:40 err whatever.

2:40 ddellacosta: what were your thoughts wrt secretary?

2:41 muhoo: noprompt: i'd heard there was someone doing clojure out there. cool.

2:41 it'll be fun to put faces to names at cljwest

2:41 seangrove: muhoo: Costs money to record/stream

2:41 Or else we'd do it for Cljs

2:41 ddellacosta: noprompt: oh, I find that we use it in a way where we have standard loading/unloading actions, and so I was wrapping the defroute macro...in a macro, but it's not ideal

2:42 noprompt: I was thinking it would be useful to provide a mechanism for before/after filters

2:42 noprompt: just functions really

2:42 muhoo: dsrx: it's possible that the hardcore clojure folks in LA are burnt out on meetups. volunteering might help, bringing in new blood might help, i dunno.

2:42 ddellacosta: noprompt: I see that you're moving more and more in the direction of making the routes match the way compojure works

2:50 arubin: seangrove: Any idea what the costs are like?

2:50 seangrove: arubin: I don't, couldn't even find someone to do it for the last meetup :P

2:50 arubin: Seems like a perennial problem that should be solved by now.

2:51 Chicago's Clojure group is quite active.

2:51 seangrove: arubin: Maybe.. it's pretty intensive, I think. Equipment, labor and expertise for operating it, time for editing, and uploading

2:52 chare: cch

2:52 i return.

2:52 bob2: https://www.refheap.com/49987 <- I seem to be misunderstanding how map destructuring works, top line is from (println (keys themap)) just before the call

2:54 ugh, duh

2:54 muhoo: extra & ?

2:54 bob2: it's not a rest argument

2:57 noprompt: ddellacosta: yes that's the idea and eventually it'll probably end up doubling as cljs+browser/cljs+node/clj router

2:58 ddellacosta: if weavejester had merged the cljx pull requests things might be different.

2:58 ddellacosta: noprompt: oh, didn't see those

2:58 seangrove: noprompt: Well, cljx is a bit of a nightmare

2:58 noprompt: seangrove: not really.

2:58 ddellacosta: seangrove: why do you think so?

2:59 noprompt: seangrove: garden has a pretty large cljx set up and it's really not that bad.

2:59 seangrove: noprompt: Getting sablono to run locally in a project subdir took a bunch of tweaking of source paths, etc. We use it in our production apps too, and it's just finicky.

2:59 It's definitely cool and useful, but looking forward to feature-expressions in clojure proper

2:59 noprompt: sure there's a little more thought/effort but really people should be thinking of that when releasing a librry.

3:00 seangrove: i did not run into that w/ sablono.

3:00 seangrove: noprompt: When using sablono, or hacking on it as a subproject of your project?

3:01 noprompt: seangrove: ah, no i didn't try that. yes, that can be an issue.

3:01 seangrove: noprompt: Definitely consuming it isn't bad at all

3:02 noprompt: ddellacosta: i did borrow clout's route lexing style.

3:03 ddellacosta: but i changed i did things a bit differently.

3:03 :(

3:03 gah, getting tired...

3:04 ddellacosta: seangrove, noprompt: I think the most confusing part of CLJX is integrating it smoothly; that should be documented better (case in point: https://github.com/lynaghk/cljx/pull/30)

3:04 noprompt: the render-route thing was something we came across on our own though and thought was a good idea.

3:04 ddellacosta: but once you get it going it is wonderful to use

3:06 seangrove: ddellacosta: Well, I think feature-expressions will probably help clear some of it up by standardizing things

3:06 noprompt: seangrove: definitely.

3:11 ddellacosta: feel free to open an issue if you have a good idea btw. :)

3:11 seangrove: bbloom: Alright, https://www.refheap.com/53df41f4d9e74dc128bd9ead6 works very well for subcomponents that are all the same height, and it's pretty speedy as well. Handling varying heights seems very difficult though, I'm not sure of how we can do it since we won't know anything about the components rendered dimensions until after rendering. It's a difficult challenge at midnight, certainly.

3:11 ddellacosta: noprompt: re: filters/pre-/post- actions, does it seem like something you folks would be into?

3:12 noprompt: we actually wrote a library for the same thing in Compojure

3:12 noprompt: ddellacosta: handlers has been on my mind, but i'm not sure what that would look like.

3:13 ddellacosta: you *can* do that before and after secretary/dispatch! though.

3:13 ddellacosta: i guess we'd have to see what it looks like to get an idea of what you're thinking and how we could fit it in.

3:13 ddellacosta: noprompt: well, it's less relevant there since it would mean duplicating some effort in parsing and interpreting the route args

3:14 ryanf: I momentarily forgot what cljx was, saw react stuff, and was therefore thinking cljx was xml literals for clojurescript :)

3:15 ddellacosta: noprompt: for example, we have a Page protocol, which has loading and unloading functions. Every time you load a page it calls a load function mapped to a Page mapped to the current route. Similarly, it unloads the last Page (also based on history fragment)

3:15 noprompt: ddellacosta: oh. now, that sounds pretty cool.

3:15 ddellacosta: that would actually plug in really well w/ the om style of thinking too.

3:15 ddellacosta: noprompt: and that's not even all of it. But it is the same exact thing every time, and it happens post-routing. So I originally wrote a macro that wrapped defroute. But 1.0 broke it because of how it checks for names

3:16 noprompt: yeah. :-)

3:16 noprompt: ...which is not a bad thing, 'cause I didn't like the macro wrapping the macro anyways

3:16 noprompt: but I think it would be slicker to just offer this somehow within secretary if you guys are game

3:17 noprompt: yeah, it is exactly made for working w/Om actually.

3:17 noprompt: but obviously could be anything, not just Om

3:17 seangrove: ryanf: Could be a great April 1st announcement :)

3:18 noprompt: ddellacosta: yeah, that's an awesome idea. IWillNavigate/INavigate/IDidNavigate?

3:18 ddellacosta: noprompt: oooooh, interesting, yeah

3:18 seangrove: noprompt: seems nice, yeah

3:18 ddellacosta: noprompt: alright, let me get a pull request together then. :-)

3:19 noprompt: dammit you guys. :)

3:19 i'm never gonna get garden 2.0.0 out the door w/ his nonsense. :P

3:20 ddellacosta: noprompt: haha...well, I'm do my best to get you something in the next few days

3:21 noprompt: although that probably means more like the end of the week

3:21 noprompt: ddellacosta: which means by the end of the month? :P

3:21 ddellacosta: you can always just open the issue first and reference our chat here. :)

3:21 ddellacosta: noprompt: no comment

3:21 noprompt: hahaha

3:21 no kidding.

3:21 ddellacosta: ;-)

3:22 noprompt: first I have to finish my blog post on protocols in CLJS, and my om-svg post...*sigh*. Oh right, and then there's my job

3:22 anyways, seriously, will get you something ASAP

3:22 we need this at work so I have an excuse

3:23 noprompt: whenever i see "patch welcome" in an issue i've learned to read that as "i'm busy and would love to see this feature but you do it." :P

3:23 ddellacosta: i'm mostly interested in how that would work.

3:25 ddellacosta: the dispatch-fn would need to implement IFn i think.

3:25 well maybe not.

3:26 no, secretary/dispatch! would be an alias for INavigate (navigate [...])

3:26 ddellacosta: noprompt: hmm, I dunno. My first instinct is to simply have something in defroute that checks if there is a pre- or post- fn, and runs it before or after the form passed in

3:27 noprompt: I dunno, it depends. I to fully read through secretary first, I've only read bits and pieces so far

3:27 noprompt: ddellacosta: we could do a hangout and i could explain the internals quickly.

3:27 :)

3:28 it's fairly strait forward though.

3:28 all of this stuff should be implemented via protocols though.

3:28 ddellacosta: noprompt: yeah, not that I object to a hangout but I think it's relatively clear (looking at it now)

3:28 noprompt: checking for a pre/post map is just screaming protocol.

3:29 ddellacosta: yeah, I suppose you're right

3:29 noprompt: but then, would you expect people to pass a type into the route, or do something w/reify like with Om?

3:29 noprompt: behavioral/domain questions generally are a good sign there's a protocol.

3:30 ddellacosta: noprompt: it feels a bit like overkill for common usage patterns. At the same time, I suspect this is something you'd want to expose to users of the API, rather than people implementing something on top of it.

3:30 noprompt: ddellacosta: i'm not sure.

3:30 ddellacosta: noprompt: I'm not debating that it could/should be a protocol, I'm just not sure on what level it would work

3:30 noprompt: ddellacosta: yes, you nailed it.

3:31 ddellacosta: noprompt: I mean, I guess it could be an option, used kind of like how you can do om/component or (reify <Protocols> ...)

3:31 noprompt: ...in Om

3:31 noprompt: ddellacosta: this has been my experience using garden. i'm not expsosing enought protocols which is limiting the usage of the library.

3:31 ddellacosta: noprompt: gotcha.

3:32 noprompt: ddellacosta: i just now rounding out the corners of a new ISelector protocol for garden which makes selectors SUPER powerful.

3:32 other protocols will follow suit. :)

3:32 ddellacosta: nice. :-)

3:33 noprompt: yeah, I feel like you don't want to require people to all of a sudden add more ceremony to the basic (defroute "/myroute" params <form>) structure

3:34 noprompt: maybe that could be the default, and then you could optionally do (defroute "/myroute params (reify IPreRouteAction (pre-route-action [this] ...) IRouteAction (route-action [this] ...) IPostRouteAction (post-route-action [this] ...))

3:35 noprompt: and by default in defroute it could simply check if the form passed in satisfies any of those protocols...

3:36 seangrove: bbloom: #react suggested a good approach. I could see it causing major layout thrashing, but I'm going to sleep on it and see if I wake up with any solutions to that.

3:36 ddellacosta: noprompt: ha, that could be awesome 'cause then you could define something like a Page type which implemented IPreRouteAction ...yeah, this is starting to make more sense. What do you think?

3:37 noprompt: ddellacosta: yeah, i think it's a good route to go. i think we should definitely flesh it out in an issue.

3:37 ddellacosta: noprompt: okay, I'll start with this and we can go from there.

3:37 noprompt: ddellacosta: i want this now. because it's a problem we faced recently where something like that would have been awesome.

3:38 ddellacosta: noprompt: yeah, I suspect it could be really useful for many use-cases.

3:40 noprompt: ddellacosta: it's just going to take a minute to think of how the api i should look.

3:40 fwiw, my keyboard is acting really weird...

3:41 something about this mac.

3:41 ddellacosta: noprompt: yeah definitely. Also, I want to be clear that I'm proposing something that is post-dispatch, but the names you suggested above (IWillNavigate/INavigate/IDidNavigate) imply that you are thinking of pre-navigation as well. However, I think that would have to be something unrelated to defroute...maybe?

3:44 noprompt: ddellacosta: it's hard to say because ultimately what all of that means is keeping track of a) where you were b) where you are going and c) where you are.

3:45 maybe it's a bad idea?

3:45 just sketching here.

3:45 ddellacosta: noprompt: yeah, I don't know

3:45 noprompt: I think it's important obviously not to try to do *too* much in the lib, certainly

3:45 noprompt: => true

3:46 ddellacosta: noprompt: history stuff I think should not be incorporated, but it wouldn't be bad to have a protocol, for example, for previous

3:46 seangrove: noprompt ddellacosta: I assume the IWillNavigate would be perfect for setting up e.g. the go loops waiting for data to be loaded

3:46 noprompt: ddellacosta: the other thing we were interested in, is the possibiity of faking verbs (ie. GET/POST/PUT/DELETE)

3:47 seangrove: Or possibly could be anyway... maybe not. Anyway, headed to bed for now

3:47 noprompt: ddellacosta, seangrove well i think if we put our heads together and think through everything we might be able to come up w/ something.

3:47 ddellacosta: noprompt: what is the motivation for that? I'm wary of mapping too much to HTTP patterns, but I haven't thought too deeply about it anyways

3:47 seangrove: G'night!

3:47 ddellacosta: goodnight seangrove!

3:47 noprompt: seangrove: sweet dreams lol!

3:57 ddellacosta: noprompt: https://github.com/gf3/secretary/issues/21

3:58 noprompt: and with that I'm going to go help my wife with some stuff--thanks for talking through this! Look forward to next steps. As soon as we decide what we want I'll put together a pull request. :-)

3:58 noprompt: ddellacosta: awesome. this looks like a great start! thanks!

3:59 ddellacosta: noprompt: definitely, thank you!

4:36 szymanowski: Hi, how can i turn a string to regex? like "foo" => #"foo"

4:37 amalloy: &(doc re-pattern)

4:37 lazybot: β‡’ "([s]); Returns an instance of java.util.regex.Pattern, for use, e.g. in re-matcher."

4:38 szymanowski: thank you

5:03 john2x: anyone using midje-mode here? is there anything else I need to do besides turning it on? I'm trying `C-c ,`, but it can't resolve symbol 'fact'. (I've already `use`d midje.sweet)

5:26 _oggy: is there a de facto standard parsing library for clojure? incremental parsing would be a plus, if it doesn't add too much complexity

6:24 muhoo: stackoverflow is pretty useless for puzzling out css issues when using cljs. the #1 top rated answer is always "use this jquery plugin! +1!" :-/

6:24 systemfault: :/

6:24 How is cljs related to css though?

6:26 muhoo: css/dom issues in general. the solution usually seems to use a jquery plugin to hack around limitations and/or cross-browser problems

6:27 systemfault: Well, normalization is jQuery's strength

6:27 muhoo: indeed. but cljs is based on closure and seems to get good backwards-compatibility browser support via that

6:28 i dunno. there's probably a much simpler solution but i'll have to sleep on it. just spent hours wading through bootstrap and other css documentation, trying experiments, etc

6:29 systemfault: Oh

6:29 I've yet to try cljs... still learning basic clojure at the moment.

6:29 muhoo: i was just venting that the top answers aren't "here's an explanation of the theory of why this is a problem, how to fix it, etc", it's just "use this jquery plugin and your worries are solved"

6:29 systemfault: What is your problem? Is it something big?

6:40 ddellacosta: muhoo: I've done a lot of CLJS + CSS + dealing with stupid browser issues, so if you describe the process may be able to help.

6:46 Phonatacid: Hi. Im loooking for doubly-linked versions of clojure datastructures. I'm almost certain I once stumbled upon a github repo (something in core of "contrib") that offered exactly this. Can't find it again though. Any help ?

6:55 szymanowski: hello, i've got a string like this: "(+|#)" and would like to make a regex with it, when I try this: (re-pattern "(+|#)") it return an error because the + is not escaped, How can I do?

6:57 since I can't escape the + char in a regular string

7:00 arcatan: you can escape it with \\. (re-pattern "(\\+|#)")

7:02 szymanowski: thank you

7:10 one last thing, I would like to replace all occurences of the + character in a string with \\+ but when i'm trying (clojure.string/replace "foo+" #"\+" "\\+") it returns "foo+" instead of "foo\+"

7:15 sorry my question was nonsense

10:29 seangrove: ddellacosta: Anything you can add here? https://github.com/r0man/sablono/issues/18

10:42 john______: Could someone tell me what is meant by annotations?

11:01 gfredericks: TimMc: my point was that *compile-files* doesn't refer to the source files, it refers to the .class files

11:14 ddellacosta: seangrove: added a comment. And on that note, I'm off to bed...

11:18 TimMc: gfredericks: OK, that was my understanding as well.

11:19 gfredericks: TimMc: ah; you said something about loading sources out of the db and that sounded orthogonal

11:19 TimMc: gfredericks: So gen-class requires writing to disk?

11:20 gfredericks: TimMc: I don't know for sure about that...where does compiled code normally go when not doing AOT?

11:21 just stays in memory via a special classloader?

11:21 TimMc: That's what I was imagining.

11:21 gfredericks: I expect gen-class can work that way

11:21 TimMc: Is there some other way I should be trying to dynamically load up code that extends a concrete class?

11:22 gfredericks: ,(doc *compile-files*)

11:22 clojurebot: "; Set to true when compiling files, false otherwise."

11:22 gfredericks: TimMc: proxy can extend a class

11:22 TimMc: Yeah, but what does "compiling files" mean?

11:22 gfredericks: Bonus, I need the result to be a Class to pass around.

11:22 gfredericks: ,(proxy [java.util.List] [])

11:22 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: iterator>

11:23 gfredericks: ,(type (proxy [java.util.List] []))

11:23 clojurebot: sandbox.proxy$java.lang.Object$List$3ec5a5e

11:23 gfredericks: ,(class (proxy [java.util.List] []))

11:23 clojurebot: sandbox.proxy$java.lang.Object$List$3ec5a5e

11:23 gfredericks: ^ is that good enough?

11:24 TimMc: I thought a proxy's Class wasn't reliable to work with.

11:24 gfredericks: maybe just across JVM restarts? dunno really

11:25 TimMc: Let me give context: I'm working with Zuul, and if I want to give it filters written in Clojure, I need to be able to give it a Class file on demand when it hands me a blob of source code.

11:25 gfredericks: from the filesystem?

11:26 TimMc: Yeah, but I think it can also load from DB.

11:26 I think it then calls the constructor, which is a problem for proxy and reify.

11:26 gfredericks: why?

11:26 clojurebot: gfredericks: because you can't handle the truth!

11:26 gfredericks: (is it a problem)

11:27 TimMc: Well, maybe I'm wrong. Let me give this a try in REPL.

11:27 gfredericks: (reify) gives you a 0-arg constructor

11:28 if you're gonna use locals though that's a different story :)

11:28 TimMc: So I had been trying to use :gen-class, but Compiler/compile wasn't giving me a Class.

11:28 gfredericks: well gen-class lets you pick the class name

11:28 so presumably you could just look it up afterwards?

11:28 TimMc: It's not there. :-(

11:28 gfredericks: ,(gen-class)

11:28 clojurebot: nil

11:29 gfredericks: ,(gen-class :name 'Taco)

11:29 clojurebot: nil

11:29 TimMc: compile returns nil, so I was reading and inspecting the ns form and trying to use Class/forName to get the Class, but it was saying ClssNotFoundException or whatever.

11:29 gfredericks: ,Taco

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

11:29 gfredericks: ,(binding [*compile-files* true] (gen-class :name 'Taco))

11:29 clojurebot: nil

11:30 gfredericks: ,'Taco

11:30 clojurebot: Taco

11:30 gfredericks: ,(Taco.)

11:30 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Taco, compiling:(NO_SOURCE_PATH:0:0)>

11:30 gfredericks: oh right

11:31 TimMc: ,(class (.newInstance (class (proxy [java.util.LinkedList] []))))

11:31 clojurebot: sandbox.proxy$java.util.LinkedList$0

11:32 TimMc: \o/ Maybe that will work!

11:33 gfredericks: ...

11:33 is (class (.newInstance foo)) not the identity?

11:33 TimMc: Just checking. :-)

11:37 gfredericks: But not the other way around.

11:38 ,(.toString (proxy [java.util.LinkedList] [] (toString [] "override")))

11:38 clojurebot: "override"

11:38 TimMc: ,(.toString (.newInstance (class (proxy [java.util.LinkedList] [] (toString [] "override")))))

11:38 clojurebot: "[]"

12:17 bbloom: seangrove: back. was sleeping :-) i'm looking at https://www.refheap.com/53df41f4d9e74dc128bd9ead6 now

12:18 looks like you're doing a parallel map over the sub-component-datas w/ range (which is just a map-with-index, no?)

12:19 koreth_: Any opinions on Enlive vs. Selmer vs. Fleet vs. ??? I really like Enlive's conceptual model but every time I've tried to use it, it's felt like I'm writing twice as much code as the problem ought to require. Is that just a learning curve?

12:22 bbloom: seangrove: for that parallel map, i'd just do (subvec (mapv vector sub-component-datas (range)) ...)

12:23 or just (->> (map vector sub-component-datas (range)) (drop N) (take M)))

12:23 where N is calculated by scroll position

12:23 and M is calculated by component height

12:25 seangrove: M is just (Math/ceil (* (/ viewport-height (* sub-component-height (count sub-component-datas)))) over-draw-factor))

12:25 seangrove: holy hell those names are long :-P

12:25 TimMc: gfredericks: Anyway, I'll let you know if I come up with something. Until I come up with something better, I'll just rely on AOT and not on dynamic loading; I'll write a Clojure "compiler" that just loads the AOT .class file and returns the Class. :-P

12:26 dissipate: bbloom, 'stack-panel' looks too long. can you break that function up?

12:28 bbloom: dissipate: not my code :-P

12:28 dissipate: also, it doesn't seem that bad to me...

12:28 dissipate: bbloom, functions should be small. i would like to see the unit tests for that beast.

12:28 bbloom: dissipate: oh that's right, you're a troll

12:29 dissipate: bbloom, how so?

12:38 mischov: koreth_: I used to love Enlive/Laser, but I was converted to using Selmer because I feel Selmer code is just more maintainable than Enlive/Laser code.

12:39 koreth_: Enlive/Laser gives you some amazing power, though, and they're good options.

12:39 seangrove: bbloom: Will clean it up in a bit. Was thinking about how to handle the variable heights, think I have it.

12:40 bbloom: But the (drop N) will affect the scroll position

12:44 koreth_: mischov: Haven't looked at Laser yet -- will check that out before I give up on the approach. Thanks. I definitely see what you mean, though. My last job was at a place that used PHP for HTML rendering and, for all its warts, PHP does have the benefit of letting you iterate really quickly on user interface code. But the code-in-HTML approach makes it harder to go as quickly from mockups to code.

12:44 dissipate: koreth_, what about AngularJS?

12:47 koreth_: dissipate: Is that client-side-only? Seemed like it when I took a brief look a while back, but I haven't actually tried it. Search engine friendliness is my big worry with client-side rendering.

12:47 (Obviously not an issue for any non-public-facing sites, though.)

12:47 dissipate: koreth_, yeah, it renders client side

12:48 seangrove: bbloom: If I'm dropping/re-rendering components all the time, then I guess I'll essentially need to fake the scroll position

12:48 Raynes: https://github.com/cgrand/enlive/blob/master/src/net/cgrand/enlive_html.clj#L135 conjconjconjconjconj

12:49 koreth_: I do wish Google and others would run JS engines in their web scrapers so they could meaningfully index client-rendered sites, but I guess then you'd have people trying to write sites to crash their crawlers with infinite loops and such.

12:50 seangrove: koreth_: Just punish the site if it crashes, same as they do now for empty sites

12:51 dissipate: koreth_, Google recommends using 'HTMLUnit' for that: https://developers.google.com/webmasters/ajax-crawling/docs/html-snapshot

12:52 koreth_: dissipate: Huh, hadn't seen that page before. Thanks!

12:53 dissipate: koreth_, np. at the last company i worked at, we actually used a 3rd party plugin for SEO. it basically stuffed a bunch of keywords into the pages, non-visible to the user of course.

13:10 bbloom: seangrove: you don't need to fake it, you just put an oversized child in there

13:10 seangrove: sorry, i assumed you were already doing that

13:11 seangrove: bbloom: Ok, that makes sense

13:11 bbloom: you have the viewport div w/ overflow scroll and you have the content div, which is mostly empty space, then you absolutely position in there

13:11 seangrove: bbloom: Got it. working on it now.

13:18 muhoo: how do i define inline css styles in om? i tried :style {:width "500px"} in the props, but no luck

13:18 dnolen_: #js {:style #js {:width "500px"}}

13:18 muhoo: ^

13:20 muhoo: dnolen_: thanks for confirming that. that's what i did, i must have done something else wrong somewhere else

13:20 and thank you for om! this is fantastic.

13:31 seangrove: I'm using om/update!, why am I getting an error about manipulating cursors outside of render phase with this? https://www.refheap.com/4e0bbea0eda926b30b7aad607

13:37 danielszmulewicz: seangrove: Because you're in a go block.

13:37 You need to deref the cursor

13:37 seangrove: danielszmulewicz: In order to om/update! it?

13:37 danielszmulewicz: seangrove: yes, try (om/update! @panel-data :scroll-position inc)

13:38 seangrove: danielszmulewicz: Same error

13:38 https://www.refheap.com/45aedb90486bd8981e5676c47

13:38 (just to make sure that looks right)

13:39 danielszmulewicz: seangrove: Looks right, but if you get the same error, it's something else.

13:40 seangrove: danielszmulewicz: It's not important for the time being, I was just using it to test some functionality, but I'l like to know why

13:41 danielszmulewicz: seangrove: I was facing the same kind of problems. Trying to wrap my head around certain errors. I'm still learning. If you discover something, pls share your wisdom.

13:42 seangrove: danielszmulewicz: Will do, thanks

13:46 muhoo: danielszmulewicz: seangrove: i can confirm that derefing inside a go block makes that error goes away, and works

13:46 danielszmulewicz: muhoo: Nice.

13:46 muhoo: for reading but om/transact! wants the un-derefed cursor, it seems

13:47 so (if (:foo @app) (om/transact! app somestuff))

13:55 goldfeld: seangrove: i saw the next clojurescript meetup is march 31, not sure if it's even a good thing for a meetup to have one-time attenders, but wouldn't in be possible to have it thu or fri after clojure west? i'll only be in sf for the week, maybe others too who could show up

13:57 muhoo: so, this is the react-ish way to listen for a resize. is there a more om-ish way to do it? http://stackoverflow.com/questions/19014250/reactjs-rerender-on-browser-resize

13:57 i'm not sure if adding event handlers is very om.

13:58 sorry, official react docs, not sure if i should literally translate it into om or do something else: http://facebook.github.io/react/tips/dom-event-listeners.html

14:05 seangrove: goldfeld: I see, so instead of the last Monday of the month as usual, make an exception and do it Thursday (day after Clojure/West) for out-of-towners to come?

14:10 goldfeld: seangrove: i know it may be too much to ask since many people will be busy out of clojure west and will have to present lightning talks at the meetup..

14:10 whodidthis: react probs has nothing to do with browser size so event listeners are the correct approach

14:11 seangrove: goldfeld: I think that's a reasonable idea. I'll send an email out to the group to get people's reaction

14:12 goldfeld: seangrove: that would be truly amazing. i know i extended my trip into thursday and friday precisely looking forward to post-clojurewest followups and opportunities like this

14:13 seangrove: especially since i'm very immersed in cljs and integration with nodejs right now, as opposed to jvm-based clojure

14:13 dnolen_: seangrove: that should work, did you enable source maps to determine if the error is what you think it is?

14:15 goldfeld: seangrove: thanks anyhow for considering regardless of how it turns out

14:15 seangrove: dnolen_: Yeah, I'll come back ot it later

14:16 goldfeld: No problem of course, sending the message now

14:16 Oh, jesus, it already filled up :P

14:17 goldfeld: oh, i see

14:17 seangrove: goldfeld: don't worry, Etsy lets us have 50 people, I just set it at 20 to keep the size small

14:22 dnolen_: danielszmulewicz: you can't deref if you want to use update!

14:22 sveri: hi, i am using midje for my unit tests, how can i test something like this: (:keyword map) => (not (nil?))?

14:25 seangrove: goldfeld: Email sent, we'll see how it goes

14:26 goldfeld: seangrove: awesome! i guess i can check the meetup event for updates?

14:26 seangrove: goldfeld: Yeah, please do so

14:30 benmoss: is there any way in Chrome to get an error object's "stack" method to return source-mapped lines?

14:31 or to jump from the js line to the cljs line?

14:31 noprompt: benmoss: hmm. the stack traces themselves usually should show the source files.

14:31 dnolen_: benmoss: should just work

14:31 benmoss: they do when they print the uncaught exception

14:32 but if you catch it and call stack i get js lines

14:32 dnolen_: benmoss: nothing special you need to do in the debugger or profile tools

14:32 benmoss: refresh, also make sure to clear breakpoints (things get weird over multiple compiles)

14:33 benmoss: http://i.imgur.com/d5jy2iQ.png'

14:33 this is just from using "Pause on uncaught exceptions"

14:35 dnolen_: benmoss: you should be looking at the debugger if you want to navigate the stack, not the console

14:36 seangrove: bbloom: Ok, definition om/set-state! that's causing it here: https://www.refheap.com/50275

14:36 Actual error http://dl.dropbox.com/u/412963/Screenshots/d7.png

14:36 benmoss: yeah, the problem is the exception's stack is different from the current stack

14:37 the stack at the time it's thrown that is

14:37 steckerhalter: any idea how I encode a string that has \ΓΌ inside so that it becomes %FC ? I need to imitate that encoding to scrape a website. it seems that the characters > 127 are "hex" encoded like this. the others are not touched

14:37 benmoss: so i have to determine the original stack, insert a breakpoint there

14:37 just wondering why exception.stack() isn't mapped

14:38 seangrove: dnolen_: It looks like owner in this case is the data passed into stack-panel, maybe I'm mixing up the order somehow

14:38 bbloom: seangrove: huh?

14:38 steckerhalter: I tried MimeUtility from Java but couldn't get that behavior. als URLEncoder does something different. hmm

14:38 bbloom: seangrove: was that for dnolen_ ?

14:39 seangrove: bbloom: It was, sorry. Almost have virtualized rendering with variable-size subcomponents going though. Last two steps are to get the sub-components reporting their bounding-rect on render, and the figure out how to catch scroll events

14:40 bbloom: seangrove: i'm curious to find out what overdraw factor will make sense. i suspect it may depend on the number of items that fit in the viewport

14:40 seangrove: b/c the browser will scroll faster than you'll get scroll events & re-render

14:40 seangrove: bbloom: Ah, I guess the other bit is to handle window resizing

14:40 bbloom: Yeah, I suspect there will be some flicker of blank content on fast scrolls

14:41 I'll think about how to smooth that out once we get there though

14:41 bbloom: yeah, we can cross/burn that bridge when we get to it

14:41 dnolen_: seangrove: that's just way too much context for me to look at

14:41 bbloom: lots of mitigation strategies

14:41 seangrove: dnolen_: Heh, ignore it then

14:42 dnolen_: benmoss: no idea, but what are you trying to do that requires this?

14:43 steckerhalter: ok, found it out it's ISO-8859-1

14:44 benmoss: dnolen_: just trying to debug an error on upgrading Om. Tried using "Pause on uncaught" to try to figure it out, wondered if anyone had a solution to that issue i've seen

14:45 dnolen_: benmoss: it just works for me, are you using :optimizations :none?

14:45 clojurebot: Excuse me?

14:46 benmoss: dnolen_: yeah. the stack method gives you source mapped stuff? weird. console.trace() works, but ex.stack() doesn't.

14:47 dnolen_: benmoss: I never use the stack method, I just use the debugger

14:47 benmoss: right

14:47 but this is a case where i don't know where to insert a debugger

14:47 dnolen_: benmoss: if you catch uncaught exception why do you need to know?

14:47 in the debugger

14:47 benmoss: because the thrown exception has a stack that is different from the current stack

14:48 muhoo: so, i'm sorry about maybe being more fuzzy about this than i should, but what is the om-like way to force a bunch of elements to re-render? i.e. at window resize time?

14:48 dnolen_: benmoss: and why is that? (or you don't know)

14:49 muhoo: those elements should probably listen to the window resize event and either set-state! or transact! to trigger refresh

14:49 muhoo: dnolen_: perfect, thanks

14:51 benmoss: dnolen_: dunno, it's React's renderComponent call stack, so it's shifting scope

14:51 dnolen_: benmoss: React 0.9.0?

14:51 benmoss: 0.8.0

14:52 dnolen_: benmoss: yeah I think the exception stuff is much improved in 0.9.0, 0.8.0 could be very confusing at times

14:52 benmoss: hm, weird, i just upgraded to om 0.5 and did a cljsbuild clean, let me try that again

14:53 definitely one of the more annoying workflow things right now

14:54 oh, my page is requiring react directly, duh

14:55 why isn't it recommended to use externs for development?

14:56 dnolen_: benmoss: they don't do anything outside of advanced

14:56 benmoss: ah

14:58 muhoo: this has been a damn good cocktail of deps and setup for me so far: https://www.refheap.com/50279

14:59 _oggy: (f 1) throws an exception; (type (f 1)) returns instaparse.gll.Failure. how do i catch this particular exception in a catch (how do i access the type)?

14:59 `cbp`: muhoo: no core.match? :)

15:00 muhoo: haven't needed it yet.

15:00 or sablono, etc. might tho

15:01 `cbp`: core.match is my best weapon against nil

15:01 muhoo: really? good to know.

15:05 hmm, looks like core.match could be a great weapon against nested ifs too.

15:07 dnolen_: muhoo: just be careful w/ core.match inside core.async - they do not play well together

15:08 muhoo: also good to know, thanks

15:09 _oggy: erg, stupid question. instaparse.gll.Failure is not an exception, just a regular return value

15:12 seangrove: dnolen_: Somehow it looks like I'm in a state where owner.props.__om_cursor is just a normal cljs.core.PersistentArrayMap - is that normal?

15:13 dnolen_: seangrove: if you constructed a value that you passed to a component that you didn't get out of the app-state - yes

15:13 seangrove: dnolen_: Ah, that's it then

15:14 dnolen_: Should I not be doing that, generally?

15:14 dnolen_: seangrove: it just depends - it's sometimes useful to construct such values

15:15 seangrove: dnolen_: Should I convert them to a cursor then, so I can use om/set-state! in the component I'm building?

15:15 dnolen_: seangrove: but if you want component local state to work you need to (om/build foo-view (om/graft random-value cursor))

15:15 seangrove: dnolen_: Ah, ok, I hadn't realized what om/graft was for

15:16 benmoss: dnolen_: is it a typo on https://github.com/swannodette/om/wiki/Documentation under "IInitState" that the IRenderState function is named "render" as opposed to "render-state"?

15:16 dnolen_: benmoss: typo, feel free to fix

15:17 benmoss: was hoping i had discovered why my build-all call was never getting to my render-state

15:23 hm, if i change "build-all" to "build", it calls my component's render-state fn, but as "build-all" it never does. no exceptions, just the "bunch of weird numbers on the page" error i've seen before

15:32 dnolen_: benmoss: can you gist/refheap your build-all call?

15:37 benmoss: dnolen_: https://gist.github.com/benmoss/9313406

15:38 dnolen_: benmoss: so that build-all call won't work anymore - build-all no longer returns an array

15:38 benmoss: ah

15:38 dnolen_: (apply dom/tr #js {:key (:position (first %))} (om/build-all square % options))

15:46 benmoss: thanks

16:03 codebx: Hi guys. I was curious what the best way was to insert a new map into an existing one. For instance, I have {:company {:info {:total_files 10}}} and I'd like to add in {:uploader "name" :files 1} inside of the :info key so that it looks like {:company {:info {:total_files 10 {:uploader "name" :files 1}}}} -- hopefully that makes sense. I've been struggling with this for several hours sadly enough.

16:04 i've been trying something similar to (assoc-in data_map [:company :info] {:uploader "name" :files 1}) and it just seems to overwrite whatever is currently within :info already

16:04 bbloom: codebx: {:total_files 10 {:uploader "name" :files 1}} doesn't make sense. you need to have key/value pairs

16:04 ,{:total_files 10 {:uploader "name" :files 1}}

16:04 clojurebot: #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>

16:05 bbloom: see?

16:05 hyPiRion: codebx: bbloom beat me to it. You need to attach it with a key

16:06 bbloom: codebx: i'm just guessing for your data, but you probably want something like {:total_files 10 :uploaders []}

16:06 then you can use update-in with conj:

16:06 codebx: oh I think I see. so I need a key associated with the {:uploader "name" :files 1} map like uploader_list: {:uploader "Name" :files 1} i suppose?

16:06 btw - I really appreciate your help (bbloom / hyPirion)

16:06 bbloom: ,(update-in {:company {:info {:total_files 10 :uploaders []}}} [:company :info :uploaders] conj {:uploader "name" :files 1})

16:06 clojurebot: {:company {:info {:total_files 10, :uploaders [{:uploader "name", :files 1}]}}}

16:06 codebx: okay that's a good idea too

16:06 Bronsa: codebx: maybe you want ##(update-in {:company {:info {:total_files 10}}} [:company :info] merge {:uploader "name" :files 1}) ?

16:06 lazybot: β‡’ {:company {:info {:files 1, :uploader "name", :total_files 10}}}

16:07 codebx: Yeah I was hoping to have something like {:company {:info {:total_files 1 {:uploader "john" :files 10} {:uploader "tim" :files 10} {:uploader "robert" :files 15}}}}

16:08 i'll take your advice though - I like using a vector

16:08 (thanks Bronsa, bbloom)

16:09 bbloom: codebx: yeah, what you want is kinda XML-ish, where you have a node with attributes and children. we don't have any idea of attributes+children in clojure, we just have maps w/ key value pairs, so you just invent a key for the children & put a vector there

16:09 codebx: that's perfect, bbloom. I'm glad I asked! :)

16:11 seangrove: Off-by-one. Getting close though...

16:11 bbloom: seangrove: haha, off by one error? surely that means you need some kind of sliding window abstraction :-)

16:12 seangrove: bbloom: Going to lean on you on how to clean this code up once it's ready

16:12 bbloom: seangrove: heh ok

16:12 seangrove: nevermind that i have no idea what any of Om's API methods do

16:12 it's hilarious every time i talk to david and i'm like "yeah, i've never even tried Om, but I tell everybody it's the best thing ever"

16:13 seangrove: bbloom: Semi-informed evangelists are the best ;)

16:14 bbloom: seangrove: i understand the underlying model deeply, so the communication challenge is primary vocabulary :-)

16:15 akyte: Anyone here do any android dev with neko?

16:17 seangrove: Is there an equivalent of ffirst for llast?

16:18 bbloom: (comp last butlast) ?

16:18 why do you need that/ heh

16:18 amalloy: bbloom: i think he means (comp last last)

16:18 bbloom: oh

16:18 amalloy: but yeah, trying to use that suggests you should have a vector or something :P

16:18 bbloom: either which way, not sure why that's necessary :-)

16:19 Raynes: llllllast

16:20 bbloom: i think there's at least one lisp implementation out there that parses symbols of the form /c[ad]+r/

16:20 cadddadadaddddar

16:20 amalloy: bbloom: i have a macro that does that in clojure, for laughs

16:21 bbloom: amalloy: i'm laughing

16:21 amalloy: (with-cxrs (... (caaddaddaddar xs)))

16:21 bbloom: haha

16:21 benmoss: how would you dynamically create instances of different record types?

16:21 bbloom: do you also have with-fflls

16:21 ?

16:22 ffnlffexters

16:22 amalloy: sadly no. left as an exercise for the reader

16:22 benmoss: like if you have the record types [Foo Bar Baz] and you want to map over them and create instances of each

16:24 ah, "new" works for that

16:24 codebx: Is there a good way to update the value inside a specific map of a vector? so I have something like this: {:ruby {:info {:uploaders [{:uploader "Joseph", :files 1} {:uploader "Greg", :files 1]}} and I want to update the :files by passing the value to inc. I can get the vector doing (get-in data_map [:ruby :info :uploaders]) but how in the world do I then get a particular map out of the vector and then update the :files value for

16:24 it? Say that I wanted to update the :files for :uploader "Greg" -- is there an easy way? I suppose I need to use one of the walk functions?

16:27 amalloy: uhhhhh, new will only work with a class literal. you can't map it over a seq

16:27 benmoss: codebx: you can just use "update-in" to get to the vector and then map to update the ones you want. probably a better way out there, but that should work I think

16:28 amalloy: codebx: well, your structure doesn't make it possible to do very efficiently - if possible, best would be to have a map from uploader to files, rather than a list of uploader/file pairs

16:29 codebx: I see. Thank you gentlemen. I appreciate it

16:30 amalloy: with what you have, the best you can do is something awful like (update-in m [:ruby :info] (fn [m] (map m (fn [x] (if (= (:uploader x) "Greg") (update-in x [:files] inc) x)))))

16:30 benmoss: but yeah {:ruby {:info {:uploaders {:uploader "Joseph", :files 1} {:uploader "Greg", :files 1]}}

16:30 err

16:32 {:ruby {:info {:uploaders {"Joseph" {:files 1} "Greg" {:files 1}}} would allow for just update-in to work

16:33 codebx: Thanks amalloy and benmoss. I'll definitely think about both solutions. this really requires a new way of thinking.. it's blowing my mind

16:33 your help is much appreciated though. thank you!

16:33 amalloy: codebx: well, choosing good data structures is a good idea even in imperative languages :)

16:34 codebx: fair enough :)

16:34 benmoss: amalloy: so is there a way to construct a dynamic class? i see now "new" doesn't work inside a map

16:34 amalloy: benmoss: have you thought about whether you'd be happier if you just used hashmaps instead of N record types?

16:35 benmoss: well the reason i am switching to types is so I can use protocols instead of multimethods

16:35 amalloy: why?

16:35 clojurebot: why is the ram gone

16:36 amalloy: i mean, there are good reasons to use protocols and records, but they're not great as a default choice

16:37 bbloom: so far, i have regretted records 9/10 times i've used them

16:37 benmoss: mostly because Schema doesn't have a macro for annotating defmethods, and because I read that multimethods should be "rarely needed" or something

16:37 so no good reasons, just trying it out to see how it would fit

16:37 bbloom: benmoss: do you have a pressing need to use Schema?

16:38 benmoss: of course not

16:38 bbloom: yeah, i think the correct answer here is: back to basics :-) strip out scheme, switch to maps, use multimethods if you really have something polymorphic

16:38 only use records if you've profiled & proven you need to

16:38 only use protocols if you've got a deftype

16:39 and only use deftype if you truly have some new thing that isn't a vector, map, etc

16:39 benmoss: aye aye captain

16:39 bbloom: final step: be happy :-)

16:40 benmoss: just felt like the "types" of my maps were starting to feel overwhelming, so thought I'd try Schema to see what it could offer

16:40 bbloom: benmoss: when faced with excessive complexity, the solution is to reduce complexity, not to label it

16:40 there are good reasons to use schema, but unless YOU can articulate them, then you shouldn't use it

16:41 benmoss: so you have to learn what they are by not using it?

16:41 bbloom: heh, well that's one way

16:41 benmoss: very zen

16:42 bbloom: realize that the prismatic guys have a many rich APIs (their public one and their internal services) and they treat the various components of even a single jvm process as separate services

16:42 seangrove: bbloom: Ok missing a few scroll/resize handling, but with hardcoded M/N this works https://www.refheap.com/50377

16:42 sveri: hi, using the friend library, is there a way to get the username of the currently loggedin user?

16:43 seangrove: Handles variable-sized subcomponents by reporting back to SP on the componentDidMount event

16:43 bbloom: benmoss: they use schema for internal documentation and dynamic "type checking" so to speak, but more importantly, they use it to generate API endpoints, enduser documentation, etc. it's a metalevel that you shouldn't adopt unless you need it

16:43 seangrove: you got it running somewhere i can try it?

16:44 seangrove: bbloom: Let me see if I can get off of master Om/Sablono and push

16:44 bbloom: surely we need OmFiddle

16:45 seangrove: i'd rename "sub-com-datas" to simply "items"

16:45 benmoss: seangrove: when did IDisplayName get added? hadn't seen that before

16:46 bbloom: seangrove: then :sub-com can be clearly :item-component

16:46 and :sub-com-opts can be :item-options

16:46 seangrove: benmoss: It's in Om master. dnolen_ Would you be willing to push a point update with IDisplayName added?

16:46 bbloom: seangrove: and :sub-com-height => :item-height

16:47 seangrove: what's this height best guess thing about?

16:47 is that for variable heights?

16:48 seangrove: bbloom: Yeah, it's for the user to supply a reasonable best guess about what the items are going to be, cut down on jumping

16:48 bob2: I've had the same probplurtunity as benmoss - many map 'types' being created in a bunch of places. what're some approaches for ensuring consistent sets of keys etc?

16:49 bbloom: seangrove: this feels more complex than i'd expect, but i have to soak it in for a bit

16:50 seangrove: so you're storing each component's height?

16:51 assuming they are variable?

16:51 bacon1989: Hello, I was wondering if there's a limit on how big a vector can be within clojure, and if there's a way to change how big it can be?

16:51 seangrove: bbloom: Yeah, in order to calculate the offset for the next component

16:51 And yes, assuming they're variable

16:51 bacon1989: I have a 400 element vector that won't seem to evaluate

16:52 bob2: 400 is small

16:52 what are you doing and what happens when you do it?

16:52 dnolen_: seangrove: yes but will have to be later

16:52 bbloom: seangrove: is this storing ALL the heights, or only the heights for the rendered items?

16:52 bacon1989: it says "runtime: unmatched delimiter"

16:52 i'll post the code, one sec

16:53 seangrove: bbloom: All the heights right now

16:53 bbloom: Honestly could just store the offsets

16:53 bacon1989: ooo...

16:54 does putting a zero infront of a number make it octal?

16:54 http://pastebin.com/MQKY0cdC

16:54 bbloom: seangrove: i think you should start by splitting this up more. you could easily make a separate ScrollPanel component

16:54 bacon1989: it doens't affect my problem

16:54 bob2: yes

16:55 bbloom: seangrove: i'm trying to figure out how to handle the "measuring"

16:55 seangrove: it's a two-step process w/ upward communication, which is tricky. which is why i suggested a fixed height to start

16:55 seangrove: bbloom: The measuring is in there currently

16:56 bbloom: seangrove: yeah, but the channel approach seems hairy to me

16:56 seangrove: We use a sub-component 'panel-entry' that listens for render, grabs the node, gets the height, and passes it up

16:56 bbloom: Definitely open to suggestions in that case

16:57 bacon1989: so I took out all of the zeros, and it seems to be compiling now

16:57 not really sure what the deal is with that

16:58 bob2: unmatched delimiter just sounds like you had a typo

16:58 I kinda worry that you were doing eval or something though

16:58 bbloom: seangrove: doesn't Om work with the react event model? why not just have an on-resize event?

16:59 seangrove: bbloom: For detecting the window change?

16:59 bbloom: Or for the window problem?

16:59 err, measuring-problem*

16:59 bbloom: seangrove: measuring

17:01 seangrove: bbloom: Sounds like it could be a good idea

17:01 vt240: anyone here done any genetic programming with clojure?

17:01 bbloom: seangrove: involving channels just seems like unnecessary overhead & complexity: you just need a way for the parent to ask the last known size of the child

17:02 Foxboron: vt240: i know a friend's master thesis was genetic programming

17:02 in clojure

17:02 bbloom: seangrove: so the parent can just keep a map of key=>height

17:02 seangrove: btw: http://referencesource-beta.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/VirtualizingStackPanel.cs#22e1b692280b25fa

17:02 seangrove: much more feature rich, but holy hell tha tcode is verbose :-P

17:03 seangrove: bbloom: 404?

17:03 bbloom: Nevermind, erc mangled the url

17:03 bbloom: seangrove: try http://referencesource-beta.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/VirtualizingStackPanel.cs

17:04 seangrove: Will look at it in just a moment

17:04 bbloom: seangrove: it's also got features like scroll-to-child and scroll-to-index and recycling of objects in memory

17:04 absurdly complex though

17:05 they have an interesting layout model though: it's a two pass system: 1) Measure and 2) Arrange

17:05 measure is a post order walk, then arrange is a preorder walk

17:06 in the measure pass, children are offered an amount of space (potentially infinite on either axis), then they respond by saying how much space they'd like

17:07 in the arrange pass, parents tell children which layout rectangle slot they've been assigned, and children attempt to fit themselves in to that space

17:09 sadly, react doesn't have a way to walk the tree outside of the render pass

17:11 but it shouldn't be an issue in general: just pick an initial guess for children sizes, assign rectangles to children during render and propegate actual measurements as events, storing responses in the parent, overriding the guess, then the next render frame will patch it up

17:11 if your initial guess is good, then it will render fine, otherwise, you might get one frame of pop

17:12 i dunno if you can force the react render pass to happen multiple times before yielding to the browser. if so, then just pump render until the measurements stableize

17:15 seangrove: anyway, all that is to say: simplify by making splitting out the scroll-panel in to it's own component

17:16 seangrove: bbloom: Yeah, that's similar to what I was doing with the stored heights/offsets

17:17 bbloom: What does the scroll-panel do? Just to div with overflow-y: scroll and an oversized child?

17:17 Also, won't the over-sized child + absolutely positioning elements prevent a resize event from happening?

17:19 bbloom: seangrove: the scroll-panel should also embody the scroll-position state

17:20 seangrove: by resize event, i guess i mean a synthetic resize event. maybe call it "measure"

17:23 this gets messy though b/c we start getting in to a desire for subclassing and behavior composition :-/

17:23 like that panel-entry thing is just some wrapper that does the measurement logic, yeah?

17:24 i guess you can just stack together components....

17:24 seangrove: bbloom: Yeah, it isn't clear how to handle extension beyond composing in Om, yet

17:24 bbloom: seangrove: btw, how's this all work so far? much faster than the many item issue you had before?

17:24 seangrove: bbloom: I'll keep working on it, but you should be able to get it running locally very quickly https://github.com/sgrove/omchaya/tree/stack-panel-com

17:25 bbloom: It seems faster, but I'll wait until things are tidied up before taking actual measurements

17:25 bbloom: seangrove: would help if you get rid of the linear space for measurements & only measure items in view

17:26 seangrove: bbloom: Linear space?

17:26 bbloom: Here's the current source https://github.com/sgrove/omchaya/blob/stack-panel-com/src/omchaya/components/stack_panel.cljs, appreciate all the guidance

17:27 bbloom: seangrove: by linear i'm just referring to the fact that you don't technically need to measure off-screen components

17:28 you can approximate their size and if you scale your approximation by distance to the beginning or end, it will smoothly converge, baring some browser quirks

17:28 (doc last)

17:28 clojurebot: "([coll]); Return the last item in coll, in linear time"

17:28 bbloom: yeah, you want peek

17:28 (doc peek)

17:28 clojurebot: "([coll]); For a list or queue, same as first, for a vector, same as, but much more efficient than, last. If the collection is empty, returns nil."

17:30 bbloom: gotta go, good luck

17:59 seangrove: dnolen_: Do you see any reason why onScroll wouldn't work with Om? Have you gotten it to work in any examples?

18:01 dnolen_: seangrove: never tried it no idea

18:01 seangrove: though I don't see how there could be any issues

18:02 seangrove: dnolen_: Thanks. I'll keep digging then

18:03 jlpeters: Folks, I'd love some help on extracting all of the 'names' from a set of subvalues from a nested hash. The use case here is I have a json blob for a user and I'm trying to extract the names of all of the 'roles' that the user has. I can drill down to the "roles" within the parsed json but can't figure out how to iterate over that to just extract the names

18:03 of those roles. For example, a user may have multiple roles such as:

18:03 http://pastebin.com/qaiu4QEL

18:03 I can use get-in to drill into a single record, for example given a user 'u' I can use "(get-in u [:roles 0 :name])" but I'd like to iterate over all of the "roles" and extract all of the "names" of those roles.

18:04 I know I'm missing something dreadfully easy here, but I'm rather new to clojure.

18:11 ryantm: jlpeters, use map

18:11 jlpeters: I've been playing with map and I must just have the syntax wrong. I'll keep working at it.

18:11 ryantm: (map :name your-vector)

18:11 clojurebot: It's greek to me.

18:13 jlpeters: Crikey, I've been massively overcomplicating that for about an hour. Thanks, ryantm

18:14 ryantm: jlpeters, you're welcome

18:19 Nyyx: epl license isn't viral is it? I can choose any license for my code with epl dependencies?

18:23 seangrove: Alright, a basic VirtualizedStackPanel https://dl.dropboxusercontent.com/u/412963/basic_virtualized_stack_panel.mov

18:25 Invoked like https://www.refheap.com/9d134d828829c1587bc0b90ef and it takes care of rendering the list in a scroll-view and only rendering the visible items + overdraw

18:26 bbloom: seangrove: i just got back from my errand :-P can you explain what's happening in this video? negative overdraw for testing?

18:26 seangrove: bbloom: I'm simulating a smaller window and having it scroll through, not rendering items at the top as the pass out of view, and not rendering items below that aren't in view yet

18:27 bbloom: There are actually 250 items in that list, but only 10 showing at any one time

18:27 bbloom: seangrove: ah ok cool. how smooth is it when it's configured for real?

18:27 seangrove: bbloom: Don't know. Moving onto the actual scroll detection now

18:33 bbloom: seangrove: btw, can you imagine how much work this would be w/o react? lol

18:33 fucking adding and removing components and all that nonsense

18:34 seangrove: bbloom: It's a lot of work with react

18:34 I don't even want to think about it with something like jQuery :P

18:34 dnolen_: seangrove: looks pretty cool!!!

18:34 seangrove: everyone will use this

18:34 seangrove: dnolen_: That's the idea. This shit just needs to be done.

18:35 Then building apps, and tooling to build apps just becomes sensible

18:37 bbloom: seangrove: another trick you can do is favor overdraw in the current direction of scrolling

18:37 seangrove: dnolen_: I was thinking about an 'OmStudio' waaaay off in the distance, something equivalent to Interface Builder. I've wanted that for years now. It'd be nice if there was a protocol for components to expose all of the keys that they care about in cursors and document them for introspection

18:40 bbloom: seangrove: i did viewport tracking for delayed loading of profile photos

18:40 in a jquery project at some point

18:40 was a PITA

18:41 basically had to find/fix a plugin for enterviewport and exitviewport events, then store loaded state on each profile tile. on enterviewport, it would swap out the little missing-photo image with the real image href

18:41 worked reasonably well, but soooo much less general

18:42 and had to hack the viewport for "overdraw" otherwise on slow connections you'd constantly see photos popping

18:43 then we discovered that pressing the [end] key in some browsers caused every damn photo to load, so had to address *that* issue

18:43 seangrove: bbloom: Were all photos the same dimensions?

18:43 bbloom: yes

18:43 that little photo-loading perf optimization turned out to be a nightmare

18:46 seangrove: here's a "mega list" impl in jquery: https://github.com/triceam/MegaList/blob/master/src/megalist.js

18:46 it doesn't work right at all w/ the scroll gesture on my mac touch pad

18:46 nearly 700 lines of js :-P

18:47 dnolen_: bbloom: madness

18:51 vt240: I just tried to do (use 'clojure.contrib.math) and it said it couldn't find it

18:51 I'm using clojure 1.5.4 - where is the expt function supposed to be?

18:52 Nyyx: anyone know why I'm getting this error on lein repl? "CompilerException java.lang.ClassNotFoundException: chip.gui.settings, compiling:(chip/gui/app.clj:21:29)"

18:54 bob2: vt240, http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go -> https://github.com/clojure/math.numeric-tower/

18:54 when doing what

18:54 vt240: thanks bob2!

18:55 Nyyx: when just doing "$ lein repl" in the project directory

18:55 vt240: I don't seem to be able to (use 'clojure.math.numeric-tower) either though

18:55 do I need to add some lein dependency?

18:55 bob2: yes

18:55 Nyyx: chip.gui.settings is a deppendency of chip.gui.app which itself is a dependency of core

18:55 bob2: and you'd want (:require [clojre.math.numeric-tower :refer expt]) not use

18:56 amalloy: meh. use is fine for playing around in a repl

18:56 plus he has two fewer errors than your suggestion, bob2 :P

18:57 vt240: I'm trying to do some automatic code generation, so I'm creating functions in text files and doing (load-file filename)

18:57 to experiment with genetic algorithms

18:57 bob2: heh

18:57 vt240: and some of these functions need expt

18:58 bob2: didn't realise it was repl

18:58 vt240: not sure if that's the best approach

19:00 I want to evaluate the file in a context that has a lot of math functions available

19:02 Nyyx: anyone?

19:02 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

19:04 vt240: Nyyx I'm a noob but have you tried repl deps ?

19:04 Nyyx: Why do I get this error? "CompilerException java.lang.ClassNotFoundException: chip.gui.settings, compiling:(chip/gui/app.clj:21:29)"

19:04 I thought leiningen would be smart and pull in all code required by the dependencies at the top of the core.clj?

19:06 michaniskin: Nyyx: you need to :require or :import any names or java classes from other namespaces that you use in your namespace

19:07 Nyyx: ahgg I keep forgetting I still need require even when I qualify the name fully

19:07 michaniskin: thanks

19:08 michaniskin: sure, no problem

19:22 seangrove: dnolen_: Is there a way to store local state in an Om that won't trigger a re-render?

19:22 Trying to keep track of when the user is scrolling/finished scrolling/scroll position, and so I'm trigger dozens of rerenders while scrolling

19:22 (by using om/set-state!)

19:23 dnolen_: seangrove: there isn't but it's something I've suspected would be useful.

19:23 seangrove: the question is whether it actually matters

19:23 seangrove: you're not really trigger "dozens" of re-renders - just one for the next frame

19:25 seangrove: dnolen_: But as I scroll, scroll event are continuously triggered, so I'm going to be rerendering as much as Om lets me until I stop scrolling

19:32 ,(doc partition-by)

19:32 clojurebot: "([f coll]); Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of partitions."

19:34 dnolen_: seangrove: you're never going to render more than 60fps

19:34 seangrove: dnolen_: Yes, but I don't need to re-render at all :)

19:34 And I'm cutting through a lot of items on scroll

19:35 dnolen_: seangrove: open an issue for set-state! w/o refresh and I'll think about it.

19:35 seangrove: dnolen_: Thanks will do

19:41 quarkGluonPlasma: quit

20:17 mzdravkov: I am trying to test a simple macro for making infix notation in clojure with 2 arguments: (defmacro infix [[a op b]] (op a b)). When I call with with (infix (1 + 2)) it returns 2...

20:27 saolsen: A macro should return a clojure expression

20:27 eg

20:27 (defmacro infix [[a op b]] `(~op ~a ~b))

20:28 michaniskin: or (defmacro infix [[a op b]] (list op a b)), which is what the above emits

20:30 chouser: Anyone know if core.typed adds (or could add) metadata to Clojure forms, indicating its understanding of the forms' types?

20:31 brehaut: chouser: i think it adds the type annotations these days?

20:31 chouser: I guess I should just try it.

20:32 brehaut: from memory it initially stored all that stuff in its own space but it was changed due to popular request

20:32 it may only be vars though, rather than forms in general?

20:32 chouser: hmm

20:33 mzdravkov: hm saolsen, michaniskin, thanks, those worked. Ive tried with '(op a b), but it didn't do the job (why is that, isn't the '() syntax equivalent to (list...) )

20:33 brehaut: chouser: perhaps try #typed-clojure too

20:35 chouser: brehaut: thanks!

20:40 saolsen: '(op a b) will return exactly the list "(op a b)" the ~ syntax is unquoting which evaluates the form which in this case gives the values that were passed in and it results in "(+ 1 2)"

20:44 http://www.braveclojure.com/writing-macros/ is a really good overview, there are a lot of different nuances to quoting and unquoting

21:09 quizdr: i need some debugging advice. when you get a Null Pointer Exception, it would be nice to know how to pinpoint it in some way besides just going over every form in the function call, is there a better way?

21:11 seangrove: bbloom: It's working pretty well, but I'm sure you'll have a problem with the complexity :)

21:12 bbloom: seangrove: heh, it's cool. i'm sure you or others will improve on it in time

21:13 seangrove: bbloom: I hope so. It's super simple to use at least, and pretty speedy. Going to do a gut-check test to compare it with the naive-approach (would like to automate this perf testing eventually)

21:14 Ah, forgot about window resizing though, bummer

21:24 dnolen_: seangrove: is it up somewhere?

21:25 seangrove: dnolen_: It's part of Omchaya on a branch. I can push it if you're interested in trying it

21:33 dnolen_: seangrove: sure will give it a shot later

21:33 seangrove: Alright, I'll push it in a bit, will let you know

22:19 devn: purname is really cool

22:19 purnam*

22:19 pretty sure i said that last night, but im really enjoying it

22:19 noprompt: devn: what's cool about it?

22:20 devn: noprompt: (def.n square [x] (obj :value (* x.value x.value)) vs (defn square [x] (let [o (js-obj) v (aget x "value")] (aset o "value" (* v v))) o)

22:20 https://github.com/purnam/purnam

22:21 noprompt: devn: i'm familiar w/ the library. i was just curious what you thought was interesting about that.

22:21 *it

22:21 devn: i think the testing portion of it is really nice also

22:21 noprompt: devn: yeah, but the problem w/ that is he should have extracted it as a separate lib.

22:21 kind of unfortunate.

22:21 devn: nothing precludes that from happening

22:22 "patches welcome" and all that

22:22 he asked for help maintaining on the ML

22:22 noprompt: devn: true. true. true.

22:23 personally i don't like the idea of doing keyword style lookups on js-objects unless they've been reified to work like that.

22:23 devn: i can see it both ways

22:24 designers who are already skiddish about stepping into cljs might be encouraged by it

22:25 noprompt: imho this is bad: https://github.com/purnam/purnam.native/blob/master/src/purnam/native.cljs

22:26 there's no need to "patch" everything when most of the time you can get by w/ reify and plain old (.-property obj)

22:27 that kind of code makes it difficult to see where the boundaries between clojurescript and javascript art.

22:27 *are

22:27 i don't think it's a good idea to bring newbies in to cljs by teaching them bad patterns.

22:30 bob2: do you think the angular-clojurescript integration stuff is a bad idea also?

22:30 noprompt: bob2: yes.

22:30 bob2: (I'm looking at using it for my next thing)

22:30 noprompt: bob2: angular and cljs are like mixing oil and water.

22:31 bob2: the style encouraged by react/reagent/om is better suited for cljs.

22:31 i like angular but i found it too painful and weird to use from cljs.

22:32 also, i'm not sure if it's a good idea to wrap an entire framework in cljs.

22:33 wrap libraries.

22:33 bob2: intereseting

22:36 munderwo: Hi all. Im using compojure and have an optional http Params. Im passing the parameters in directly, but sometimes I get an error when they are not supplied. I'm using a (param :key) form to extract the parameter, but is there a way I can set a default on that extract if the key doesn't exist?

22:36 noprompt: munderwo: what's your route look like?

22:37 munderwo: make a paste on refhead w/ your error. :)

22:39 munderwo: noprompt: https://www.refheap.com/50639 ..

22:39 That should be everything that you need.

22:39 All of the params into trucks list are optional (both current-location and distance)

22:40 also I'm not sure if I should be using read-string to convert the distance string into an integer.

22:41 its going to be a float, but I couldn't find the equivalent for parse-int

22:41 noprompt: munderwo: well the problem is w/ read-string according to the trace. (params :distance) is nil in that case.

22:42 munderwo: noprompt: yeah, so I think I need a default value, or a better way to do it.

22:42 noprompt: munderwo: you probably want to provide some defaults like {:keys [distance] :or {distance "0"}} params, etc.

22:44 munderwo: also, read-string is probably too big of a gun. shoot for something like (Integer. distance)/(Float. distance)/parseInt etc.

22:45 munderwo: noprompt: yeah coolies. i'll see if I can work that out. links to syntax for the default values for maps? Im a total clojure n00b

22:46 noprompt: munderwo: no worries. well there's a few things you can do. a) use the destructuring syntax a mentioned above. b) use a map look up with a default value (:distance params "0")

22:46 munderwo: you can also handle that stuff in the route before you call truck-list.

22:47 munderwo: for "/food_trucks" i'm guessing your using a query string?

22:47 munderwo: noprompt: ahh cool. I think I have an inkling of how I can do it. Which is the best kind of starting point.

22:47 yup

22:48 can params come from a body?

22:48 noprompt: munderwo: i think you'll want {params :query-params}

22:49 munderwo: oh? does params mean both things?

22:49 noprompt: munderwo: ah, maybe not. nm.

22:50 munderwo: yeah, you're good. :)

22:52 munderwo: thanks for your help~!

23:22 firefaux: is there an elegant way to get a sequence of a map's keys, sorted by their values?

23:23 bob2: (sort-by (partial get somemap) (keys somemap))

23:23 or so

23:24 firefaux: that's perfect

23:25 bob2: also i don't know if partial is considered idiomatic

23:25 firefaux: would it be more idomatic to use a lambda?

23:26 bob2: i do not know

23:26 amalloy: (sort-by some-map (keys some-map))

23:26 firefaux: (fn [k] (somemap k))

23:26 bob2: ahhh duh me

23:26 firefaux: ooh

23:27 lol, that's actually what my lambda did, come to think of it

23:29 lotia: hi all. any recommendations of a libary I can use to do http content negotiation?

23:30 bob2: which part do you want to do?

23:36 amalloy: actually, (vals (sort-by key some-map)) is probably better

23:39 firefaux: amalloy: are you talking about my question about sorting keys?

23:40 amalloy: indeed

23:40 firefaux: amalloy: that doesn't do what you think it does

23:40 I think it sorts the values by key

23:40 I was doing the opposite

23:40 and swapping vals for keys doesn't make it work, like I thought it might

23:41 oh wait

23:41 lemme try something

23:41 aha

23:41 (keys (sort-by val m))

23:41 that does it

23:50 gfredericks: in trying to use laser to do something really basic I have somehow managed A) NPE B) IOOBE C) hanging the process

23:51 AimHere: I don't know what IOOBE means, but I do hope the last four letters stand for 'Out of Body Experience'

23:51 gfredericks: ,([] 1)

23:51 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

23:52 AimHere: Heh, I've seen many of those before, but it didn't click

23:53 gfredericks: I've never seen the acronym before

23:54 fun clojure golfing: pick a built in java exception and try to find the shortest way to throw it

Logging service provided by n01se.net