Podcast Search

Under the Radar

4: Unexpected Complexity

Select a time to play from there. The line being spoken is highlighted as the audio plays.

0:00:00Welcome back to Under the Radar, a show about independent iOS development.

0:00:04I'm Marco Arment.

0:00:05And I'm David Smith.

0:00:06Under the Radar is never longer than 30 minutes, so let's get started.

0:00:10So today I think we wanted to talk about probably one of the most common

0:00:15but yet challenging parts of being a developer, at least in my experience,

0:00:19and that deals with unexpected complexity.

0:00:23When you start off working on something and you have kind of an expectation

0:00:27of how complicated it's going to be to do, what it's going to look like, the effort involved,

0:00:30the time involved. And then you sit down, you open up Xcode, you start programming, and it turns out

0:00:36that it's a complete nightmare and it's going to be way more effort and way more work.

0:00:41And that experience happens so often that I think having a good process and mindset about dealing

0:00:48with it is one of the very important things of being able to ship software in a reasonable time

0:00:54and reasonable quality.

0:00:56And I think we both recently had an experience

0:00:57that kind of fell into that category,

0:01:00and so this episode I think will be more

0:01:03of a case study style in terms of talking

0:01:06through our experiences.

0:01:07And so I believe that is the experience that you had

0:01:11when you were working on the streaming engine

0:01:12for Overcast, am I right?

0:01:14- Oh yeah.

0:01:15I mean streaming as a feature,

0:01:17so Overcast is a podcast player,

0:01:19and the built-in Apple APIs for playing media using AVPlayer,

0:01:24most of that stuff supports streaming out of the box.

0:01:29You don't really have to do much to enable it.

0:01:32I mean, depending on how much you want your interface

0:01:35to behave, you don't necessarily have to do anything.

0:01:37So it's relatively easy to support streaming media

0:01:41just as well as you do locally played media

0:01:43if you're using AVPlayer.

0:01:45But one of Overcast's biggest selling features,

0:01:47and one of the things that makes it most compelling,

0:01:50both to me and to many of the users,

0:01:52is my custom audio engine with a feature called Smart Speed,

0:01:56where Smart Speed dynamically adjusts the playback.

0:02:00And the way it works is there's a processing function that

0:02:06needs to read in the audio samples

0:02:09in the middle of the processing stream

0:02:11and then output possibly a different number of them

0:02:15if it's speeding up the sound.

0:02:16So it might take in 500 samples,

0:02:20and then the middle of it might be silence

0:02:22as it detects silence, so it might compress that

0:02:25down to 300 samples.

0:02:26So you need the ability to inject into the processing stage

0:02:31a function that can read faster than it can output.

0:02:34And that is not possible with AVPlayer.

0:02:37There's no mechanism to do that that I have found at all.

0:02:41If anyone knows, I'm really curious,

0:02:42but I have looked many times,

0:02:44every time there's a new SDK I look,

0:02:46I've asked Apple engineers at WWDC and in labs and via email, and it really does seem

0:02:51like it is just not possible with AVPlayer.

0:02:54So the way I do this is I actually just wrote the, I basically wrote my own AVPlayer.

0:02:58It's not a small task, and I'm writing at the core audio and audio units levels, and

0:03:06custom decoding of everything.

0:03:08And when you go lower level to enable this, the easiest way to do it is something called

0:03:13called the ext, geez, ext audio file API.

0:03:17And that is, that only works for locally stored files,

0:03:22it does not work for streams.

0:03:26There's a separate API, the audio file stream API

0:03:28that is lower level than that.

0:03:30And that you can supply stream data to.

0:03:33You still have to manage the fetching of the stream yourself

0:03:36and you have to manage a lot yourself.

0:03:39So the job of streaming was to convert

0:03:42from that ext audio file API that only does local files

0:03:46to the lower level audio file stream API.

0:03:49And also then build out all the UI behind it,

0:03:52build out the network fetcher,

0:03:54the actual streamer that can stream things,

0:03:56and of course make it all performant

0:03:58and responsible of data usage and memory

0:04:01and responsible of the CPU

0:04:04and also handle a whole bunch of weird edge cases.

0:04:08And I knew it was gonna be a big job going in,

0:04:11but I didn't quite realize how big,

0:04:14how many of those edge cases they would be,

0:04:16how tricky some of them would be to solve.

0:04:18And the biggest thing,

0:04:19like when we're talking about unexpected complexity,

0:04:22the biggest thing for me is unexpected time that it takes.

0:04:26You know, this is why our business is historically so bad

0:04:29at estimating time and ship dates.

0:04:32And when you're independent,

0:04:33I don't think we're any better at it.

0:04:34You know, I think in many ways, it might be worse.

0:04:38Do you find that you are good at estimating time?

0:04:41I think the honest answer is that I've stopped estimating time, or even trying to.

0:04:48I have found that it doesn't actually help.

0:04:52I have this vague sense of like, sometimes I have, the only deadline I usually have is

0:04:56a new device is being shipped, or a new OS is being shipped.

0:05:00There's something specific that like, if I want to be there on day one of the iOS 9 launch,

0:05:05then I need to have my app ready by the beginning of September.

0:05:10Other than that, I try hard to not think too much about timelines because every time I've

0:05:16tried to do that, it never works.

0:05:19The most universal experience of software engineering is you think it's going to take

0:05:24two weeks, it ends up taking four weeks.

0:05:27And that's just the reality of like, you're all like, as you, I mean, I think it sounds

0:05:32a little bit like you have the same experience.

0:05:33Like you start off thinking, okay, maybe I can do this with these high level APIs.

0:05:38like, you know, these things Apple has put together, they're tried and true, whatever.

0:05:43And you start using it and it's like, okay, it does most of what I need, but it doesn't

0:05:47do this one critical thing. And you start being like, how critical is that? Well, it's

0:05:52probably pretty critical. And so you take your next step down, and then you take your

0:05:56next step down, and then before long, you're just like re-implementing all kinds of crazy

0:06:00stuff. And you have no way of knowing superficially what that's going to look, how many love

0:06:06stacks deep, how much rewriting and rebuilding of stuff you're going to need to end up doing

0:06:11to get what you're going to do.

0:06:12And so at the end I was just like, I don't know, I'll just sort of hope for the best.

0:06:15And like other than for iOS 9 things, for those I just tend to say like how much, like

0:06:20I'll just work until I can't, I run out of time and just try and structure what I'm working

0:06:26on such that I can like, you know, not be half finished, have like half the things fully

0:06:32finished rather than all the things half finished.

0:06:35But yeah, estimating time is a complete nightmare, I find.

0:06:38- Yeah, totally.

0:06:40And we're lucky that when we're working for ourselves

0:06:44on our own products for the most part,

0:06:46our time estimates aren't that important

0:06:47'cause for the most part,

0:06:49only the users are demanding things, if anybody.

0:06:52It's not like, when you're a consultant,

0:06:55the pressure is much stronger on you

0:06:56to meet the client's deadlines.

0:06:58Or when you're working for a company,

0:07:00when you're working directly on your employer's product,

0:07:05You have similar pressures from that.

0:07:07But when you're a consultant, you have a whole different aspect of it, which is that

0:07:11the client is often directly paying you for the time that you are taking.

0:07:15And that, of course, makes it even more complex.

0:07:17We are both lucky that we are not currently in that kind of role.

0:07:20But certainly, I would say from just anecdotal evidence, it seems like the vast majority

0:07:26of iOS developers are involved in some kind of contract work.

0:07:31That seems to be the biggest chunk of the iOS work that's out there.

0:07:36Time estimates are such a nightmare there.

0:07:39We're both lucky that we can't really talk much about it, because I haven't done it in

0:07:43forever, and even when I didn't, I didn't do very much of it.

0:07:46It's been a while since you've done consulting as well, right?

0:07:48Yeah.

0:07:49I mean, the last time I did regular consulting was probably four or five years ago, something

0:07:54like that.

0:07:55I started out as a consultant.

0:07:56That was what I was doing initially, but it's been a long time since that made up any kind

0:08:01kind of significant portion of my business.

0:08:03And I learned very quickly when I was doing consulting,

0:08:06though, to not commit to time estimates as much as I could,

0:08:11because you're always gonna run into that.

0:08:13There's always some kind of complexity

0:08:15that you're not expecting.

0:08:16And if you don't plan for it,

0:08:18if you don't look at a problem and say,

0:08:20it's like the old rule of whatever you think

0:08:22it's gonna take, multiply it by three.

0:08:24- Yeah, at least.

0:08:25- You're probably well off, but yeah, I try as best,

0:08:30Like the first rule, you definitely have that experience when you start off consulting where

0:08:33you start to say like, "Oh, it's going to take such, you know, oh, that'll only be like

0:08:36a week's worth of work."

0:08:38And you commit to the client to do that and then it never ends up being a week's worth

0:08:41of work.

0:08:42It's just, that's just the reality.

0:08:43I mean, even, and I mean, with streaming, I had so many problems with, I would, I started

0:08:49it, I think three or four times.

0:08:52And I would get down a certain path or try to try to approach it in a certain way and

0:08:57and realize that it was just never gonna work.

0:09:00I was never gonna be able to complete it

0:09:01in the way I was doing it, or it just was not working,

0:09:05or I had made too many mistakes,

0:09:07or I had made too many subtle bugs

0:09:09that I couldn't find at the very low levels.

0:09:11And so I would just scrap it and start over again.

0:09:13And when you're at a big time crunch,

0:09:17you don't usually have the opportunity to do that.

0:09:19And that can be a blessing and a curse.

0:09:21If you do that too much,

0:09:23then you're wasting a whole bunch of time,

0:09:25and it's never gonna be perfect.

0:09:27It's never going to be exactly the perfect design, exactly what you want.

0:09:30And so if you have too many opportunities to cancel it and start over again, you're

0:09:33just going to kill tons of time.

0:09:35But if you don't have any opportunities to do that, which is often the case when you're

0:09:38under time pressure from a client, say, I feel like it's hard to get good quality work

0:09:43because you really do learn a lot if you try to do something, then get a chance to throw

0:09:48it away and do it over again.

0:09:49Yeah.

0:09:50Because I think one thing that I was, my experience, like whenever I've encountered these kind

0:09:54of problems, where I'm trying to deal with something that ends up being much more complicated

0:09:59than I think. I start off with a mental model for the problem that is straightforward. For

0:10:04example, the thing that I most recently ran into this with is I did a data syncing and

0:10:08merging algorithm for Pedometer++. So it takes the steps from your watch and your phone and

0:10:15gives you a unified view of them in semi-real time. At first I was like, "Oh, the mental

0:10:20model for this is great. There's HealthKit, right? I can just use HealthKit. And you can't,

0:10:24because that's not how HealthKit works, because it's not available on the watch in the way

0:10:28that shows you phone data. So I very quickly discovered that my original mental model was

0:10:33completely wrong. And so then, what my process tends to be, I have this really straightforward

0:10:38mental model, it ends up not working, and then I end up going down these crazy paths

0:10:43of incredibly complicated solutions. All of these really brittle and not really going

0:10:50to work solutions, like all kinds of crazy algorithms and merging schemes and way of

0:10:53throwing data back and forth. And you get to the end, and the times I'm most satisfied

0:10:59with my work, though, are when I end up, after all of that, with a simple solution again

0:11:04that is informed by all of those crazy paths down the way. Like, you can learn the lesson

0:11:10and be like, "Okay, actually, I don't need to do all these crazy things. Now that I understand

0:11:15the problem fully from top to bottom.

0:11:17I can say, "Okay, I don't need to worry about the data in all these crazy ways.

0:11:22I can just make all these nice simplifying assumptions about how it is because I've

0:11:28tested and verified that those work.

0:11:30And then I can build a solution that's almost as simple as the one I started off with wanting

0:11:35to build and now that actually deals with all that complexity."

0:11:38And whenever I'm able to go through that process, it starts simple, it gets horrifically

0:11:42messy and then it gets simple again.

0:11:44I know I'm doing it right.

0:11:47If ever I end up having to stop in that middle state where it's still really messy, I know

0:11:52it's going to break.

0:11:53I know it's not going to work.

0:11:55It needs to be something that I could just describe to myself in just a few sentences

0:12:00or something's probably gone wrong.

0:12:04What kind of system did you end up with to address the watchOS2 or watchkit2 sync problem?

0:12:11Because as you are very well aware,

0:12:14and as some of our audience might be,

0:12:18with WatchKit 1 apps,

0:12:20we're actually fairly straightforward and simple to make

0:12:22because they couldn't do that much,

0:12:24and because they were running on the phone

0:12:27in the app sandbox, in the same sandbox as the iPhone app,

0:12:30so that you could have a shared container,

0:12:32and the iPhone app and the Watch app

0:12:35could literally be reading and writing from the same data.

0:12:38And that's how I structured the Overcast Watch app,

0:12:40which is I just move the database file, the SQLite file,

0:12:44into the app container, and then the communication

0:12:49between the watch app and the phone app

0:12:51is limited only to basically commands and status updates.

0:12:55And all the data, the watch app reads the data

0:12:58right off the database, and the phone just tells the watch

0:13:02when it has changed, and the watch reads it.

0:13:04So it's actually very, quite simple in that way,

0:13:08'cause there is no sync issue.

0:13:10If the watch can't reach the phone at the given moment,

0:13:13you just can't use the Overcast app,

0:13:15'cause it's just, all it is is a remote control

0:13:17for the phone, so it's great.

0:13:19With watchOS 2, that shared data container

0:13:23no longer quite exists the same way, or at all, really.

0:13:26- It doesn't exist at all, yeah.

0:13:27- Right, so with watchOS 2, it is like,

0:13:30you are running two separate apps,

0:13:32and you need to figure out how they're going

0:13:34to communicate with each other,

0:13:35and there's methods to do the basics,

0:13:38but there is no automatic magical syncing that happens.

0:13:41So you have to deal with how these things

0:13:43synchronize their data yourself.

0:13:46That's one of the reasons why I haven't made

0:13:48an overcast watchOS 2 app.

0:13:51Why I just keep having the OS 1 app.

0:13:54First of all because it works well enough.

0:13:57WatchOS 2 improved watch kit reliability quite a bit

0:14:00and so the app works well enough for the most part.

0:14:03But also that it would be a major undertaking

0:14:06as you discovered, you know, it's a major undertaking

0:14:09to all of a sudden tackle these two,

0:14:11to all of a sudden take something

0:14:12that used to be a dumb remote and make it a full app

0:14:16with its own local storage

0:14:17and the problem of syncing both ways.

0:14:20And so, you know, if you take the phone away

0:14:23and you have the watch off by itself somewhere

0:14:24playing podcasts somehow,

0:14:26which is its own separate bag of hurt

0:14:28of like, you know, how capable that is right now

0:14:30in watchOS 2.0, but if you somehow do that,

0:14:34then you have to, when upon reconnection to the phone,

0:14:38you have to sync up that data again

0:14:39and resolve possible conflicts.

0:14:41And it's a very, it's a much larger problem

0:14:45than it seems upon first glance.

0:14:47Because while the APIs and everything are all very similar

0:14:50to what they were in Watch Scale 1,

0:14:53the data model is totally different.

0:14:55And that's where most of the complexity I think would lie.

0:14:58And I haven't yet decided that that's worth the investment.

0:15:01Apps for the Apple Watch are a whole separate topic,

0:15:04but I have found generally that I'm very scared

0:15:08to tackle that.

0:15:09This is one of the few times where I've spotted

0:15:10that complexity ahead of time,

0:15:13and possibly wisely, I don't know,

0:15:16but possibly wisely I'm avoiding it.

0:15:18- Yeah, 'cause I think what I've ended up having to do

0:15:21in WatchOS 2 is essentially you have to build

0:15:25two completely independent, can-run-on-their-own apps.

0:15:31Like the watch app has to be able to run entirely on its own without being able to phone home

0:15:35to the phone.

0:15:36And the phone app obviously needs to be able to run without the watch, which isn't that

0:15:40much of a stretch because that's what it does if you don't own a watch.

0:15:44And then you have to do these funny things because the communication between the two

0:15:49is not reliable, both in terms of sometimes the watch is just physically not close enough

0:15:56to the phone in order to communicate.

0:15:59And also, sometimes, just the APIs and things, I think it's because they're trying to do

0:16:04so much about power management and sometimes certain types of messages only go through

0:16:10if it's a good thing from an energy perspective to be able to do.

0:16:14Like the radios are all turned up and fired up, so hey, let's go ahead and send it right

0:16:17away.

0:16:18If they're not, maybe we'll wait and see if we are going to fire up the radio anyway for

0:16:22the next, in the next second.

0:16:24If not, then maybe we'll do it.

0:16:25And so you have to build the system that

0:16:30makes no assumptions about being able to talk to the other part,

0:16:34but still gives your user a consistent experience

0:16:37across both.

0:16:38And that's where, like for this project that I was working on,

0:16:41became the really crazy thing.

0:16:42Because a pedometer, in some ways, is very simple.

0:16:45Like both devices have a motion processor on it

0:16:49that tells you how many steps they took

0:16:51in a particular time period.

0:16:52Like that's all they do, and that's

0:16:54most of what the app is doing.

0:16:56And so I could run completely independently in terms of,

0:16:59if I could just showed you the watch's steps on the watch app

0:17:03and just showed you the phone steps on the phone app,

0:17:05it'd be trivial.

0:17:06But what I want to be able to do is obviously

0:17:08merge those together and say, which

0:17:09one is a better representation of what you're doing?

0:17:13And that is where all the crazy complexity comes in.

0:17:16Because I had a couple of things that I was like,

0:17:19so many of conflict resolution strategies

0:17:21don't really work in this scenario.

0:17:23because I can't just do simple things like who updated most recently or things because

0:17:28if I can ever, for example, make someone's step count go down, I guess I could, but conceptually

0:17:34I've always had that be like a rule for the app that if I ever, even if it was like slightly

0:17:38in error, if I ever showed you a step count, like for example, you hit your goal, right?

0:17:42Like you got 10,000 steps, confetti comes down from the screen, hooray, you did it.

0:17:46I don't want you to then like sync up with your watch and say like, oh, actually now

0:17:49we think that you did 9,000 steps.

0:17:51Like, that would be terrible, right?

0:17:53You have to withdraw somebody's confetti.

0:17:55Yeah, like, I'm sorry, your confetti now goes back up to the top of the screen and...

0:17:58Animated in reverse.

0:17:59I think that'd be awful, right?

0:18:02Play like a sad trombone.

0:18:03Yeah, and so you have to, like, a lot of my syncing stuff is about saying, like, what's

0:18:07the biggest number of steps that you've shown the user for the particular time period that

0:18:12we're looking at?

0:18:13And syncing that up so that if I ever needed to show, sort of add extra steps, I know what

0:18:20I need to add. And also I need to do that, but it's not just as simple as who's shown

0:18:26more because the nature of these devices is which one of them is going to be showing you

0:18:31a better view of the user's activity probably at any one time. When I'm walking and pushing

0:18:36my daughter in a stroller, my phone in my pocket is going to be a better idea of how

0:18:40many steps I am because my wrist is actually not moving. It's attached to a stroller pushing

0:18:44it along. But when my phone is in a backpack, or my wife runs into this a lot, her phone

0:18:51will be in her purse, but her watch is on her wrist, so then her watch is the better

0:18:55indicator of steps. So it's like having to work out a scheme that is in real time

0:19:00dynamically working out which one, based on the information we have, which we may or may

0:19:04not have all the time, looking at the two data streams and merging them together. That's

0:19:12that's the minimum threshold for having this thing work,

0:19:16is you have to have built a system that can do all that.

0:19:19And that was the complexity for me that just became like,

0:19:21wow, this is a whole bigger thing

0:19:23than I ever imagined it would be.

0:19:25- Yeah, and that's like one of the things

0:19:29that makes these unexpected complexities

0:19:32so frustrating or so powerful,

0:19:34is that, again, they're unexpected.

0:19:38You have no idea when in a project

0:19:41you're going to hit something like this

0:19:42until you hit it.

0:19:43And so like, you know, the more experience you get

0:19:47as a developer or just as a person who lives in life,

0:19:52the more experience you get,

0:19:53it becomes a little bit more likely

0:19:55that you'll spot them ahead of time

0:19:57and be able to possibly either avoid them

0:19:59or at least like budget for them.

0:20:01But there's still always like stuff that you hit

0:20:04that's unexpected and it can totally throw a project off.

0:20:07So like, you know, one thing that I do to manage this

0:20:11is if I can tell something's going to be a big hairy mess,

0:20:15a lot of times I'll just cut the feature.

0:20:17I'll just avoid it.

0:20:19I'll say, "Sorry, that's not worth doing."

0:20:21With Overcast, I knew streaming was gonna be a big deal,

0:20:24so for version 1.0, I just didn't include it.

0:20:27I couldn't ship it in time.

0:20:30I estimated that it would be a better idea

0:20:32to ship the app without streaming

0:20:34than to wait another six months to a year to add streaming.

0:20:39That turned out to be correct.

0:20:41And in the case of my watch app now,

0:20:43where I have the watchOS 1 app,

0:20:45the watchOS 2 app would be a ton of work

0:20:48and would be different and might not be better.

0:20:51It might just be different.

0:20:53I've calculated so far that at the moment

0:20:56it isn't worth investing the time in that.

0:20:57And it might never be, I don't know.

0:20:59But certainly right now it isn't worth

0:21:01investing the time in that,

0:21:02when I could instead be doing something

0:21:04with the same amount of time,

0:21:05I could instead be doing something like the Apple TV app

0:21:08or a major new feature, or even a brand new app

0:21:13if I wanted to.

0:21:14You have to really decide what's worth sinking

0:21:17all this time into, and sometimes it isn't

0:21:20the big hairy problem in front of you.

0:21:21Sometimes that problem is best off just staying unsolved.

0:21:26That feature might be better off staying unimplemented,

0:21:29or that app might be better off not being made,

0:21:32and you might be better off spending that time

0:21:34in other ways, because you can do a lot

0:21:37of low-hanging fruit in other parts of your app

0:21:40or as other apps in the same amount of time

0:21:42that you could tackle one big hairy problem in one app,

0:21:45and it might not be worth it.

0:21:46Our sponsor this week is Need.

0:21:48Go to neededition.com.

0:21:50Need is a curated retailer and lifestyle publication

0:21:53for the modern gentleman.

0:21:54Each week, Need launches new collections

0:21:56of exclusive clothing, literature, furniture, and more.

0:22:00Now earlier this month,

0:22:01coinciding with the company's second birthday,

0:22:03Need launched an all-new site expanding its availability

0:22:05into 43 countries in Europe, South America, Asia, and the Middle East. Shipping is flat

0:22:11rate for all international orders and free for all orders to the US, Canada, and Mexico,

0:22:16and all returns are free no matter where you are all over the world.

0:22:20This month, Neve has launched three collections, including their Holiday Gift Guide, featuring

0:22:24dozens of gift ideas for the holidays, many of which are under $40. Neve is designed to

0:22:29be simple, straightforward, and uncomplicated. They include prepaid return labels with all

0:22:34They offer 24/7 support and there aren't any subscriptions or stylists or other gimmicks

0:22:39to deal with.

0:22:40It's just a straightforward retailer.

0:22:42Simply come along to NeedEdition.com, peruse the latest collections and shop.

0:22:46Or don't, your choice.

0:22:48For listeners of this show, use coupon code radar for 20% off.

0:22:52That is coupon code radar at NeedEdition.com for 20% off anything.

0:22:56Thank you so much to our friends at Need for sponsoring Under the Radar.

0:23:00Getting back to one thing that you just said that I think is probably a good place to be

0:23:05winding down this discussion is, I think the thing that I've learned most, like this

0:23:09is the battle-hardened wisdom of dealing with complexity, is making sure that I'm solving

0:23:18the problem for the right reason.

0:23:21I think most of us who get into software engineering, or whatever you want to call what we do, we

0:23:26We like solving problems, and the problems that we like solving most are the most difficult,

0:23:31interesting, tricky problems. Like, that is, I think I'm in my element the most, I'm the

0:23:37most engaged, I'm the most excited about what I'm doing when I'm solving a really interesting

0:23:41problem. Like, if I'm just writing boilerplate code, that's not nearly as exciting and something

0:23:47I want to really, like, wrap my arms around and get, you know, sort of get up in the morning

0:23:50to dive into. And so the thing that I, though, then always have to keep in the back of my

0:23:54my mind when I find a problem like this, when I'm working along on a task and I find that

0:23:58there's this big unexpected bump in complexity. Like you were just saying, sometimes you're

0:24:02just worth not doing it. The thing I know I've had to teach myself some discipline with

0:24:07is that when I see a problem like that, when I seize an opportunity to really go crazy

0:24:11spelunking, dive deep down into some crazy low APIs and build this crazy cool clever

0:24:17system, make sure that I'm not just doing it because it would be intellectually fun

0:24:23and interesting. Sometimes there's a place for that, but I've definitely caught myself

0:24:28sometimes just building things because I think it would be fun and it wouldn't actually make

0:24:32my customers happier. It wouldn't actually make my products better. It would just be

0:24:37fun for me to do. I end up just going down these crazy rabbit holes and doing all these

0:24:41things and often the reality is it isn't actually as fun as I thought it was going

0:24:46to be. It's fun for the first few hours, first few days, and then you're just like

0:24:51It's like you're in this point where,

0:24:53like I always want to avoid where,

0:24:54it's like I started working on my car

0:24:56and I've taken it completely apart.

0:24:57And then I come to discover

0:25:00the fun part was taking it apart.

0:25:02The fun part is not putting it back together.

0:25:05And now I don't have a car anymore.

0:25:06That's the part where I have to catch myself

0:25:09and be like, am I really doing this for the right reason?

0:25:11Is this complexity worth the effort?

0:25:14And having that kind of taking a step back from your work

0:25:18is a sort of a habit and a discipline

0:25:20I've found has been very helpful in me making sure that I'm staying on track.

0:25:23And especially being like a one-man shop, like there's no one, I don't have a supervisor

0:25:27being like, "Huh, yeah, yeah, we're just going to cut that feature."

0:25:30That's too much.

0:25:31It has to be something that I have the ability to not just get totally sucked down these

0:25:36rabbit holes and say like, "Yes, of course, I need to do this thing because it's really

0:25:40interesting and really hard."

0:25:42Like, I need to be able to say like, "Will my customers notice if I do this?"

0:25:47And if they won't, like am I just doing this for myself?

0:25:50And if I am, like that's kinda sometimes fun,

0:25:55but that's really not a way that you're gonna be able

0:25:57to reliably ship quality products.

0:25:59You're just gonna end up with a lot of kind of like

0:26:01crazy half-built things that probably will end up

0:26:04making your app more complicated and harder to use

0:26:07for your customers in the end.

0:26:08- Yeah, that's a fantastic way to look at it.

0:26:11And we all face that dilemma because I mean look,

0:26:14we're all geeks, we all like interesting things,

0:26:17We all like keeping our brains interested

0:26:18and trying new things and approaching problems in new ways

0:26:21or doing things in better ways

0:26:22than what we did in the past.

0:26:24It's not that you should never do that,

0:26:25but that there's a balance to be struck

0:26:27and that doing that has significant time costs

0:26:31that may not be worth it.

0:26:32And doing a major rewrite of something that already works

0:26:36might also introduce brand new bugs,

0:26:37in fact, it almost certainly would,

0:26:39brand new bugs that you didn't have before

0:26:42then you'd have to go fixing that.

0:26:44And so it's just a balance.

0:26:45You need to keep yourself happy and learning

0:26:48and intellectually satisfied.

0:26:50But you also need to ship products

0:26:52and it's important to find that balance.

0:26:55And that's something that I think mostly just comes

0:26:57with experience and wisdom over time.

0:27:00It's not that you can never have fun,

0:27:02but that you should know when to have fun

0:27:05and when it's no longer fun and you need to get back to work.

0:27:09- Yeah, and I think the best lesson I've had about that

0:27:12is it's trying to have customer-focused development

0:27:15that way. It's like the time to do that, the time to solve interesting problems, is to

0:27:19find features or find apps or find ideas that solving a difficult problem will make a customer's

0:27:27life better. And like the intersection of those two things, like a really interesting

0:27:31technical problem and a real honest need or pain point in someone's life, like that's

0:27:37where really interesting and fun work happens. And if you can't sort of honestly say that

0:27:43that it's both interesting to build

0:27:45and useful for a customer,

0:27:47then you're probably not in a place

0:27:49that it's actually worth building.

0:27:51- All right, thanks a lot for listening, everybody.

0:27:53Please tell your friends about the show,

0:27:55help us spread the word,

0:27:56recommend us on Overcast,

0:27:58and we'll see you next week.