Under the Radar

Under the Radar 4: Unexpected Complexity


00:00:00   welcome back to under the radar a show

00:00:02   about independent iOS development I'm

00:00:04   Marco Arment and I'm David Smith under

00:00:06   the radar is never longer than 30

00:00:07   minutes so let's get started

00:00:09   so today I think we wanted to talk about

00:00:12   probably one of the most common but yet

00:00:15   challenging parts of being a developer

00:00:17   at least in my experience and that deals

00:00:19   with unexpected complexity when you

00:00:23   start off working on something and you

00:00:25   have a kind of an expectation of how

00:00:27   complicated it's going to be to do what

00:00:29   it's going to look like the effort

00:00:30   involved the time involved and then you

00:00:33   sit down you open up Xcode you start

00:00:35   programming and it turns out that it's a

00:00:38   complete nightmare and it's going to be

00:00:39   way more effort and way more work and

00:00:41   that experience happens so often that I

00:00:45   think having a good like process and

00:00:47   mindset about dealing with it is one of

00:00:50   the very important things of being able

00:00:51   to ship software in a reasonable time

00:00:54   and reasonable quality and I think we

00:00:56   both recently had an experience that

00:00:58   kind of fell into that category and so

00:01:01   it was kind of it's this episode I think

00:01:03   will be more of a case study style in

00:01:05   terms of talking through our experiences

00:01:07   and so I believe that is the experience

00:01:10   that you had when you were working on

00:01:11   the streaming engine for overcast am i

00:01:13   right oh yeah I mean streaming as a

00:01:16   feature you know so overcast as a

00:01:18   podcast player and the the built-in

00:01:22   Apple API is for playing media using AV

00:01:25   player

00:01:25   most of that stuff supports streaming

00:01:28   out of the box you don't really have to

00:01:30   do much to enable it or I mean depending

00:01:33   on how much you want your interface to

00:01:35   behave you don't necessarily have to do

00:01:36   anything so it's it's very it's

00:01:38   relatively easy to support streaming

00:01:41   media just as well as you do locally

00:01:43   played media if you're using AV player

00:01:44   but one of overcast biggest selling

00:01:47   features and one of the things that

00:01:48   makes it most compelling at both to me

00:01:50   and to many of the users is my custom

00:01:53   audio engine with a feature called smart

00:01:56   speed where smart speed dynamically

00:01:58   adjusts the playback and and the way it

00:02:00   works is it there's a processing

00:02:05   function that needs to read in the audio

00:02:08   samples in the middle of the processing

00:02:10   stream and then

00:02:12   output possibly a different number of

00:02:14   them if it's speeding up the sound so it

00:02:17   might it might take in 500 samples and

00:02:20   then the middle of it might be silence

00:02:22   as it detects silence so it might

00:02:24   compress that down to 300 samples so you

00:02:27   need you need the ability to inject it's

00:02:30   the pressing stage a function that can

00:02:32   read faster than it can output and that

00:02:35   is not possible with a B player there is

00:02:37   no method there's no mechanism to do

00:02:38   that that I have found at all I mean

00:02:40   really if anyone knows I'm really

00:02:41   curious but I have looked many times

00:02:44   every time there's a new SDK I look I've

00:02:46   asked Apple engineers at WB DC and in

00:02:49   labs and via email and it really does

00:02:51   seem like it was just not possible with

00:02:52   AV player so the way I do this is I

00:02:55   actually just wrote the I basically

00:02:57   wrote my own AV player it's it's a not a

00:02:59   small task and and it's I'm writing at

00:03:02   the core audio and audio units levels

00:03:04   and you know custom decoding of

00:03:07   everything and when you go lower level

00:03:09   to enable this they're the easiest way

00:03:13   to do it is something called the ext G's

00:03:16   ext audio file API and that is that only

00:03:21   works for for locally stored files it

00:03:24   does not work for streams there's a

00:03:26   separate API the audio file stream API

00:03:28   that is lower level than that and that

00:03:30   you can you can supply stream data to

00:03:33   you still have to manage the fetching of

00:03:35   the stream yourself and a lot you have

00:03:37   managed a lot yourself so the the job of

00:03:40   streaming was to convert from that ext

00:03:43   audio file API that only does local

00:03:45   files to the lower-level

00:03:47   audio file stream API and also then

00:03:50   build out all the UI behind it build at

00:03:53   the network fetcher that the actual

00:03:54   streamer that can stream things and of

00:03:56   course make it all performant and

00:03:59   responsible of data usage and memory and

00:04:01   responsible of the CPU and also handle a

00:04:06   whole bunch of weird edge cases and I I

00:04:08   knew it was gonna be a big job going in

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

00:04:14   many of those edge cases there would be

00:04:16   how tricky some of them would be to

00:04:17   solve and the biggest thing like when

00:04:20   we're talking about unexpected

00:04:20   complexity the biggest thing for me is

00:04:23   unexpected time that it takes

00:04:26   you know this is why our business is

00:04:28   historically so bad at estimating time

00:04:31   and chip dates and when you're

00:04:32   independent I don't think we're any

00:04:34   better at it you know I think in many

00:04:36   ways meant be worse

00:04:37   how do you do you find that you are good

00:04:40   at estimating time I think the honest

00:04:42   answer is that I've stopped estimating

00:04:44   time or even trying to like I have found

00:04:49   that it doesn't actually help for like I

00:04:52   have this vague sense of like I would

00:04:53   like sometimes I have that the only

00:04:55   deadline I usually have is a new devices

00:04:57   being shipped or a new OS is being

00:04:59   shipped like there's something specific

00:05:01   that like if I want to be there on day

00:05:03   one of the iOS 9 launch then I need to

00:05:06   you know be in this habit my app ready

00:05:08   by the beginning of June of September

00:05:09   like other than that I try hard to not

00:05:12   think too much about timelines because

00:05:14   every time I've tried to do that it

00:05:17   never works like that's semantics like

00:05:19   the class is the most like universal

00:05:21   experience of software engineering is

00:05:22   you think it's going to take two weeks

00:05:25   it ends up taking four weeks and that's

00:05:27   just the reality of like you're all like

00:05:30   as you I mean I think it sounds a little

00:05:32   bit like you have the same experience

00:05:33   like you start off thinking okay maybe I

00:05:35   can do this with these high-level api's

00:05:37   like you know these things apples you

00:05:40   know has put together their tried and

00:05:41   true whatever and you start using it and

00:05:43   it's like okay it does most of what I

00:05:46   need but it doesn't do this one critical

00:05:48   thing and you start being like how

00:05:50   critical is that well it's probably

00:05:52   pretty critical and so you like you step

00:05:53   you take your neck next step down and

00:05:55   then you take your next step down and

00:05:57   then before long you're just like

00:05:58   reimplemented all kinds of crazy stuff

00:06:00   and you have no way of knowing

00:06:02   superficially what that's going to look

00:06:05   how many love stacks deep how much

00:06:07   rewriting and rebuilding of stuff you're

00:06:09   gonna need to end up doing to get what

00:06:11   you're going to do and so then I was

00:06:12   just like I don't know I'll just sort of

00:06:14   hope for the best

00:06:15   and like other than for ios9 things you

00:06:18   know an idea for those I just tend to

00:06:19   say like how much like I'll just work

00:06:21   until I can't I run out of time and just

00:06:24   try and structure what I'm working on

00:06:26   such that I can like you know not not be

00:06:30   half-finished have like half the things

00:06:32   fully finished rather than all the

00:06:34   things half finished but yet estimating

00:06:37   time is a complete nightmare I find yeah

00:06:39   and and we're lucky that when we're

00:06:42   working for ourselves on our own product

00:06:45   for the most part our time estimates

00:06:47   aren't that important because for the

00:06:48   most part you know only the users are

00:06:50   demanding things if anybody it's it's

00:06:52   not like you know when you're when

00:06:54   you're a consultant the pressure is much

00:06:55   stronger on you to meet the clients

00:06:57   deadlines or when you're working for a

00:07:00   company you know when you're working

00:07:01   directly on your employer's product it's

00:07:04   you know you have similar pressures from

00:07:06   that but when you're consulting you if

00:07:08   you have a whole different aspect of it

00:07:09   which is that you know the client is

00:07:11   often directly paying you for the time

00:07:13   that you are taking and that of course

00:07:16   makes you even more complex we are both

00:07:18   lucky that we're not currently in that

00:07:19   kind of role but certainly I would I

00:07:22   would say from from just anecdotal

00:07:24   evidence it seems like the vast majority

00:07:26   of iOS developers are involved in some

00:07:28   kind of contract work that that seems to

00:07:31   be the biggest chunk of the of the iOS

00:07:34   workers out there and and time estimates

00:07:37   are such a nightmare there I've just

00:07:38   we're both lucky that we can't really

00:07:40   talk much about it because I haven't

00:07:42   done it in forever and even when I did

00:07:44   it I didn't do very much of it and you

00:07:46   it's been a while since you've been

00:07:47   consulting as well right yeah I mean

00:07:48   I've the last time I did regular

00:07:51   consulting was probably four or five

00:07:53   years ago something like that like I

00:07:55   started out as a consultant that was

00:07:56   what I was doing to initially but it's

00:07:59   been a long time since that made up any

00:08:00   kind of significant portion of my

00:08:02   business and I Helen very quickly when I

00:08:05   was doing consulting though to not

00:08:07   commit to time estimates and as much as

00:08:11   I could because you're always going to

00:08:13   run into that there's always some kind

00:08:14   of complexity that you're not expecting

00:08:15   and if you don't plan for it if you

00:08:18   don't look at a problem and say like

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

00:08:21   like whatever you think it's going to

00:08:22   take like multiply it by three and least

00:08:25   you're probably you're probably well off

00:08:27   but yeah I try as best like the first

00:08:30   rule like but if you definitely have

00:08:32   that experience when you start off

00:08:32   consulting where you start to say like

00:08:34   oh it's gonna take such you know that'll

00:08:36   only be like a week's worth of work and

00:08:38   you commit to the client to do that and

00:08:39   then it never ends up being a week's

00:08:41   worth of work it's just that's just the

00:08:43   reality I mean even and I mean with with

00:08:46   streaming I had so many problems with I

00:08:48   would I started it I think three or four

00:08:51   times and I would get down a certain

00:08:53   path or try to try to approach it in a

00:08:55   certain way and realize that it was just

00:08:58   it was just never gonna work I was never

00:09:00   gonna be able to complete it in the way

00:09:02   I was doing it or it just was not

00:09:04   working or I had made too many mistakes

00:09:06   or I had made too many subtle bugs that

00:09:09   I couldn't find at the very low levels

00:09:11   and so I would just scrap it and start

00:09:12   over again and when when you're at a big

00:09:15   time crunch you don't usually have the

00:09:18   opportunity to do that and that can be a

00:09:20   blessing and a curse you know if you do

00:09:22   that too much then you're wasting a

00:09:24   whole bunch of time and like you know

00:09:25   it's never going to be perfect it's

00:09:27   never going to be exactly the perfect

00:09:28   design exactly what you want and so if

00:09:30   you if you have too many opportunities

00:09:31   to cancel it and start over again you're

00:09:34   just gonna kill tons of time but if you

00:09:35   don't have any opportunities to do that

00:09:37   which is often the case when you're

00:09:38   under time pressure from a client say I

00:09:40   feel like it's hard to get good quality

00:09:42   work because you really do learn a lot

00:09:45   if you try to do something didn't get a

00:09:48   chance to throw it away and do it over

00:09:49   again yeah I think one thing that I was

00:09:51   my experience like whenever I've

00:09:53   encountered these kind of problems like

00:09:55   where I'm trying to deal with something

00:09:57   that ends up being really much more

00:09:58   complicated than I think like I I start

00:10:00   off with a mental model for the problem

00:10:02   that is straightforward for example the

00:10:05   thing that I would most recently ran

00:10:06   into this with is I did a data syncing

00:10:08   and merging algorithm for pedometer plus

00:10:10   plus so like it takes the steps from

00:10:13   your watch and your phone and make gives

00:10:15   you a unified view of them in semi

00:10:17   real-time which is at first I was like

00:10:19   oh the mental model for this is great

00:10:21   there's health kids right I can just use

00:10:22   health get and you can't because that's

00:10:25   not how healthy it works because it's

00:10:26   not available on the watch in the way

00:10:28   that shows you phone data so I very

00:10:30   quickly discovered that like my original

00:10:31   mental model was completely wrong and so

00:10:35   then like but I might process tends to

00:10:36   be I have this really straightforward

00:10:38   mental model it ends up not working and

00:10:40   then I end up going down these crazy

00:10:42   paths of like incredibly complicated

00:10:45   solutions like all of these really like

00:10:48   brittle and not really gonna work

00:10:50   solutions like all kinds of crazy -

00:10:52   algorithms and merging schemes and way

00:10:54   of throwing data back and forth and you

00:10:55   get to the end and the times I'm most

00:10:58   satisfied with my work though or when I

00:11:00   end up after all of that with a simple

00:11:03   solution again that is informed by all

00:11:06   of those crazy

00:11:07   paths down there down the way like you

00:11:09   can learn the lesson and be like okay

00:11:11   actually I don't need to do all these

00:11:13   crazy things now that I understand the

00:11:15   problem fully from like top to bottom I

00:11:17   can say okay I don't need to worry about

00:11:20   the data at all these in all these crazy

00:11:22   ways I can just somehow make all these

00:11:23   sort of nice simplifying assumptions

00:11:26   about how it is because I've tested and

00:11:28   verified that that those are those work

00:11:30   and then I can build like a solution

00:11:32   that's almost as simple as the one I

00:11:34   started off with wanting to build and

00:11:36   then now that actually deals with all

00:11:38   that complexity and like whenever I'm

00:11:39   able to go through that process it's

00:11:40   like it starts simple

00:11:41   it gets horrific ly messy and then it

00:11:43   gets simple again I know I've done doing

00:11:45   it right

00:11:46   Hyup if ever it is having to stop in

00:11:49   that middle state where it's still

00:11:50   really messy like I know it's gonna

00:11:52   break I know it's not gonna work like it

00:11:55   needs to be something that I could just

00:11:56   describe to myself in just like a few a

00:11:59   few sentences or something has probably

00:12:02   gone wrong what kind of system did you

00:12:05   end up with to address the the watch OS

00:12:08   2 or watch kit to sync problem because

00:12:11   you know as as you are very well aware

00:12:14   and as some of our games might be you

00:12:17   know with what watch kit 1 apps were

00:12:20   actually fairly straightforward and

00:12:22   simple to make because they couldn't do

00:12:23   that much and because they were running

00:12:25   on the phone in the app sandbox and the

00:12:28   same sandbox is the iPhone app so that

00:12:30   you could have a shared container and

00:12:31   that and the iPhone app and the watch

00:12:34   app could literally be reading and

00:12:36   running from the same data and and

00:12:38   that's how I structure the overcast

00:12:39   watch app which is I just moved the the

00:12:42   database file the SQLite file into the

00:12:45   the app container and then the the

00:12:48   communication between the watch app and

00:12:51   the phone app is limited only to

00:12:52   basically commands and status updates

00:12:55   and all the data the watch app reads the

00:12:58   data right off the database and you know

00:13:00   the phone just tells the watch when it

00:13:02   has changed and the watch reads it so

00:13:04   it's it's actually you know very quite

00:13:06   simple in that way because there is no

00:13:08   sync issue if the watch can't reach the

00:13:11   phone at the given moment you just can't

00:13:14   use the overcast app because it's all it

00:13:16   is a remote control for the phone so

00:13:19   it's great with watch OS 2

00:13:21   that that shared data container no

00:13:23   longer quite exists the same way or at

00:13:26   all really it doesn't exist at all yeah

00:13:27   right so so with watch OS 2 it is like

00:13:30   it you are running two separate apps and

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

00:13:33   to communicate with each other and there

00:13:35   you know there's method there's methods

00:13:36   to do the basics but there is no like

00:13:39   automatic magical syncing that happens

00:13:41   so you have to deal with how these

00:13:43   things synchronize their data yourself

00:13:45   that's one of the reasons why I haven't

00:13:47   made an overcast watch OS 2 app why I'm

00:13:51   just key I just keep having the the OS

00:13:53   one app first of all because it works

00:13:56   well enough in a watch I was to improved

00:13:58   watchkit reliability quite a bit and so

00:14:00   it the app works well enough for the

00:14:02   most part but also you know that it

00:14:05   would be a major undertaking as you say

00:14:06   as you discovered you know it's a major

00:14:08   undertaking - all of a sudden tackle

00:14:10   these two - all of a sudden take

00:14:12   something that used to be a dumb remote

00:14:13   and make it a full app with its own

00:14:16   local storage and the problem of syncing

00:14:19   both ways and so you know if you if you

00:14:21   take the phone away and you have the

00:14:23   watch off by itself somewhere playing

00:14:25   podcast somehow which is own separate

00:14:27   bag of hurt of like you know how capable

00:14:29   that is right now and watch iOS 2.0 but

00:14:32   if you somehow do that then you have to

00:14:35   when upon reconnection to the phone you

00:14:38   have to sync up that data again and

00:14:39   resolve possible conflicts and it's it's

00:14:42   a it's a very it's a much larger problem

00:14:45   than it seems upon first glance because

00:14:47   while the API is and everything are all

00:14:49   very similar to what they were and watch

00:14:51   oh and watch get one the the data model

00:14:54   is totally different and that's where

00:14:56   most of the complexity I think would lie

00:14:57   and I haven't yet decided that's worth

00:15:00   the investment apps for the Apple watch

00:15:02   are a whole whole separate topic but I I

00:15:05   have found generally that that I'm I'm

00:15:07   very scared to tackle that this is one

00:15:09   of the few times where I've spotted that

00:15:11   that complexity ahead of time and and

00:15:14   possibly wisely I don't know but

00:15:16   possibly wisely I'm avoiding it yeah

00:15:19   because I think what I've ended up

00:15:20   having to do in watch OS 2 is

00:15:23   essentially you have to build two

00:15:25   completely independent can run on their

00:15:29   own apps like the watch app has to be

00:15:32   able to run entirely on its own without

00:15:34   the

00:15:34   able to like phone home to the to the

00:15:37   phone the phone app obviously needs to

00:15:39   be able to run without the watch which

00:15:40   isn't that much of a stretch because

00:15:42   that's what it does if you don't own a

00:15:43   watch and then you have to do these

00:15:46   funny things because the communication

00:15:48   between the two is not reliable both in

00:15:52   terms of sometimes the watch is just

00:15:54   physically not close enough to the phone

00:15:57   in order to communicate and also

00:15:59   sometimes the just the api's and things

00:16:02   like because I think it's because

00:16:04   they're trying to do so much about power

00:16:06   management and you know sometimes

00:16:08   certain types of messages only go

00:16:09   through if it's a good you know it's a

00:16:12   good thing from a energy perspective to

00:16:13   be able to do like the radios are all

00:16:15   turned up and fired up so hey let's go

00:16:17   ahead and send it right away if they're

00:16:18   not maybe we'll wait and see if we are

00:16:20   going to fire up the radio anyway for

00:16:22   the next you know in the next second if

00:16:24   not then maybe we'll do it and so you

00:16:26   have to build the system that is very

00:16:29   head makes no assumptions about being

00:16:32   able to talk to the other part but still

00:16:34   gives your user a consistent experience

00:16:37   across both and that's where like from

00:16:40   for this project that I was working on

00:16:41   became like the really crazy thing

00:16:42   because like a pedometer in some ways is

00:16:45   very simple like both at both devices

00:16:47   have a motion processor on it that tells

00:16:50   you how many steps they took in a

00:16:51   particular time period like that's all

00:16:53   they do and that's most of what the app

00:16:54   is doing and so I could run completely

00:16:57   independently in terms of like if you

00:16:59   just if I could just showed you the

00:17:01   watch's steps on the watch app and it

00:17:03   just showed you the phone steps on the

00:17:05   phone app it'd be trivial but I want to

00:17:07   be able to do is I've seen merge those

00:17:08   together and say like which one is a

00:17:10   better representation of what you're

00:17:12   doing and that BK is where all the crazy

00:17:15   complexity comes in because I had a

00:17:17   couple of things that I was like oh so

00:17:19   many of like conflict resolution

00:17:20   strategies don't really work in this

00:17:22   scenario because I can't just do simple

00:17:24   things like who updated most recently or

00:17:26   things because if I can ever for example

00:17:29   make someone step count go down well I

00:17:32   guess I could but conceptually I've

00:17:34   always had that be like a rule for the

00:17:36   app that if I ever even if it was like

00:17:38   slightly an error if I ever showed you a

00:17:40   step count like for example you hit your

00:17:41   goal right like you got 10,000 steps

00:17:43   confetti comes down from the screen

00:17:45   hooray you did it I don't want you to

00:17:47   then like sync up with your watch and

00:17:48   say like

00:17:48   actually now we think that you did 9000

00:17:51   steps like that would be terrible

00:17:53   right to withdraw somebody's confetti

00:17:54   yeah like I'm sorry your confetti now

00:17:56   goes back up to the top of the screen

00:17:57   and animate it in Reverse

00:17:59   it's like it I think that'd be awful

00:18:01   right play like a sad trombone yeah and

00:18:04   so you have to like a lot of my syncing

00:18:05   stuff is about saying like what's the

00:18:07   biggest number of steps that you've

00:18:08   shown the user for the particular time

00:18:11   period that we're looking at and syncing

00:18:14   that up so that if I ever needed to show

00:18:18   as sort of add extra steps I have I know

00:18:20   what I need to add and also I need to do

00:18:23   that but like it's not just like as

00:18:25   simple as like who's shown more because

00:18:27   the nature of these devices is like

00:18:29   which one of them one of them is going

00:18:31   to be showing you a better view of the

00:18:32   user's activity probably at any one time

00:18:34   like when I'm walking and pushing my

00:18:36   daughter in a stroller my phone in my

00:18:39   pocket is gonna be a better idea of how

00:18:41   many steps I am because my wrist is

00:18:42   actually not moving you know it's

00:18:43   attached to a stroller pushing it along

00:18:45   but when my phone is like in a backpack

00:18:48   or in my or like my wife runs into this

00:18:50   a lot like her phone will be in her

00:18:52   purse but her watch is on her wrist so

00:18:54   then her her watch is the better

00:18:55   indicator of steps and so it's like

00:18:57   having to work out a scheme that is in

00:18:59   real-time dynamically working out which

00:19:01   one based on the information we have

00:19:03   which we may or may not have all the

00:19:05   time looking at the two data streams and

00:19:08   merging them together and like that is

00:19:10   what you end up having having said like

00:19:12   that's the the minimum threshold for

00:19:15   having this thing work is you have to

00:19:16   have built a system that can do all that

00:19:18   like that was the complexity for me that

00:19:20   just became like wow this is a whole

00:19:22   bigger thing than I would ever imagined

00:19:24   it would be yeah and this and that's

00:19:27   like one of the one of the things that

00:19:29   makes these unexpected complexities so

00:19:32   so frustrating or so powerful is that

00:19:37   again they're unexpected you have no

00:19:39   idea when in a project you're going to

00:19:41   hit something like this until you hit it

00:19:43   and head so like you know it the more

00:19:45   experience you get as a developer or

00:19:48   just as a person who lives in life then

00:19:51   the more experience you get it becomes a

00:19:54   little bit more likely that you'll spot

00:19:56   them ahead of time and and be able to

00:19:58   possibly either avoid them or at least

00:19:59   at least like budget for them but

00:20:02   they're still

00:20:02   always like stuff that you hit it's

00:20:04   unexpected and it can totally throw a

00:20:07   project off so like you know one thing

00:20:09   that I do to manage this is if I if I

00:20:13   can tell something is going to be a big

00:20:14   hairy mess a lot of times I'll just cut

00:20:17   the feature I'll just you know I'll just

00:20:18   avoid it I'll say sorry that's that's

00:20:20   not worth doing we know with overcast

00:20:22   I knew streaming was going to be a big

00:20:23   deal so for version 1.0 I just didn't

00:20:26   include it i I couldn't ship it in time

00:20:29   I thought it is tomato that it would be

00:20:31   a better idea to ship the app without

00:20:33   streaming than to wait another six

00:20:36   months to a year to tube add streaming

00:20:39   that turn out to be correct and in the

00:20:41   case of my watch app now where I I have

00:20:44   the watch OS one app the watch OS two

00:20:46   app would be a ton of work and and would

00:20:49   be different and might not be better you

00:20:51   know my it might just be different I

00:20:53   calculated so far that at the moment it

00:20:56   isn't worth investing the time in that

00:20:57   and it might never be I don't know but

00:21:00   certainly right now it isn't worth

00:21:01   investing with time in that when I could

00:21:03   instead be doing something with the same

00:21:04   amount of time I can instead be doing

00:21:06   something like the Apple TV app or or a

00:21:09   major new feature or a new e and even a

00:21:12   brand new app if I wanted to like I you

00:21:14   have to really decide what's worth

00:21:16   syncing all this time into and sometimes

00:21:19   it isn't the big hairy problem in front

00:21:21   of you sometimes that problem is best

00:21:23   off just staying unsolved that feature

00:21:26   might be better off staying

00:21:27   unimplemented and or that app that might

00:21:31   be better off not being made and you

00:21:32   might be better off spending that time

00:21:33   in other ways because you can do a lot

00:21:36   of low-hanging fruit in other parts of

00:21:39   your app or as other apps in the same at

00:21:42   a time that you could tackle one big

00:21:43   hairy problem in one app and it might

00:21:45   not be worth it our sponsor this week is

00:21:48   need to go to need addition com need is

00:21:51   a curated retailer and lifestyle

00:21:52   publication for the modern gentlemen

00:21:54   each week need launches new collections

00:21:56   of exclusive clothing literature

00:21:58   furniture and more now earlier this

00:22:01   month coinciding with the company's

00:22:02   second birthday need luncheon all new

00:22:04   site expanding its availability into 43

00:22:06   countries in Europe South America Asia

00:22:09   and the Middle East

00:22:10   shipping is flat rate for all

00:22:11   international orders and free for all

00:22:13   orders to the US Canada and

00:22:15   Mexico and all returns are free no

00:22:18   matter where you are all over the world

00:22:19   this month Neda's launched three

00:22:21   collections including their holiday gift

00:22:23   guide featuring dozens of gift ideas for

00:22:25   the holidays many of which are under $40

00:22:28   neat is designed to be simple

00:22:29   straightforward and uncomplicated

00:22:31   they include prepaid return labels with

00:22:33   all shipments there for 24/7 support and

00:22:36   there aren't any subscriptions or

00:22:38   stylists or other gimmicks to deal with

00:22:39   it's just a straightforward retailer

00:22:41   simply come along to neat addition com

00:22:44   peruse the latest collections and shop

00:22:46   or don't your choice for listeners of

00:22:49   this show use coupon code read our for

00:22:51   20% off that is coupon code radar at

00:22:54   neat addition calm for 20% off anything

00:22:56   thank you so much to our friends at need

00:22:58   for sponsoring under the radar

00:23:00   getting back to one thing that you just

00:23:02   said that I think is probably a good

00:23:04   place to do binding down this discussion

00:23:06   is I think the thing that I've learned

00:23:08   most like this is the like the

00:23:10   battle-hardened wisdom of dealing with

00:23:12   complexity is making sure that I'm

00:23:16   solving the the problem for the right

00:23:19   reason I think most of us who get into

00:23:22   software engineering or whatever you

00:23:24   want to call what we do we like solving

00:23:27   problems and the problems that we like

00:23:29   solving most are the most difficult

00:23:31   interesting tricky problems like if that

00:23:34   is I think I'm mu I'm in my element the

00:23:36   most I'm the most engaged I'm the most

00:23:38   excited about what I'm doing when I'm

00:23:40   solving a really interesting problem

00:23:41   like if I'm just writing boilerplate

00:23:43   code that's not nearly as exciting and

00:23:47   something I want to really like wrap my

00:23:48   arms around and get you know sort of get

00:23:49   up in the morning to dive into and so

00:23:52   the thing that I though then always have

00:23:53   to keep in the back of my mind when I

00:23:55   find a problem like this when I'm

00:23:56   working along on a task and I find that

00:23:58   there's this big unexpected bump in

00:23:59   complexity like you were just saying

00:24:02   like sometimes you're just worth not

00:24:03   doing it like I think I know I've had to

00:24:05   teach myself some discipline with is

00:24:07   that I see when I see a problem like

00:24:08   that when I seize an opportunity to

00:24:10   really like you'd go crazy spelunking

00:24:12   like dive deep down into some crazy low

00:24:14   api's and like build this crazy cool

00:24:16   clever system make sure that I'm not

00:24:19   just doing it like because it would be

00:24:21   intellectually fun and interesting like

00:24:24   sometimes there's a place for that but

00:24:25   I've definitely caught myself sometimes

00:24:28   just building things

00:24:29   because I think it would be fun and it

00:24:32   wouldn't actually make my customers

00:24:33   happier it wouldn't actually make my

00:24:34   products better it would just be fun for

00:24:37   me to do and I end up going down you

00:24:40   know these crazy rabbit holes and doing

00:24:41   all these things and often the reality

00:24:44   is it isn't actually as fun as I thought

00:24:45   it was gonna be like it's fun for the

00:24:48   first few out for the first few hours

00:24:49   first few days and then you just like

00:24:51   it's like you're in this point where

00:24:52   like I will always want to avoid where

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

00:24:56   and I've taken it completely apart and

00:24:57   like the NIF I've come to discover like

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

00:25:03   part is not putting it back together and

00:25:04   now I don't have a car anymore

00:25:06   like that's the part where I have to

00:25:08   catch myself and be like am I really

00:25:10   doing this for the right reason is this

00:25:11   complexity worth the effort and having

00:25:15   that kind of taking a step back from

00:25:16   your work is a sort of a habit and a

00:25:19   discipline that I found has been very

00:25:21   helpful in me making sure that I'm

00:25:22   staying on track and especially being

00:25:24   like a one-man shop like there's no one

00:25:26   I don't have a supervisor being like huh

00:25:28   yeah yeah we're just gonna cut that

00:25:30   feature that's that's too much it has to

00:25:32   be something that I have the ability to

00:25:34   not just totally suck down these rabbit

00:25:37   holes and say like yes of course I

00:25:39   needed to do this thing because it's

00:25:40   really interesting and really hard like

00:25:43   I need to be able to say like will this

00:25:44   will look well my customers notice if I

00:25:46   do this and if they won't like am I just

00:25:49   doing this for myself and if I am like

00:25:52   that's kind of sometimes fun but that's

00:25:55   really not a way that you're gonna be

00:25:56   able to reliably ship quality products

00:25:59   you're just gonna end up with a lot of

00:26:00   kind of like crazy half-built things

00:26:02   that probably will end up making your

00:26:04   app more complicated and harder to use

00:26:06   for your customers in the end yeah

00:26:09   that's a fantastic way to look at it and

00:26:11   we all face that that dilemma because I

00:26:13   mean look we've we're all geeks we all

00:26:15   like interesting things we all like

00:26:17   keeping our brains interested and try

00:26:19   new things and approaching problems and

00:26:20   new ways or doing things in better ways

00:26:22   than what we did in the past

00:26:23   it's not that you should never do that

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

00:26:27   and that that doing that has significant

00:26:29   time costs that may not be worth it

00:26:32   and and you know doing like a major

00:26:34   rewrite of something that already works

00:26:35   might also introduce brand-new bugs in

00:26:37   fact it almost certainly would brand new

00:26:39   bugs that you that you didn't have

00:26:42   before they need to get to go facing

00:26:43   and so it's just a balance you need to

00:26:46   keep yourself happy

00:26:47   and learning and intellectually

00:26:49   satisfied but you also need to ship

00:26:51   products and and it's important to find

00:26:54   that balance and and that's something

00:26:55   that I think mostly just comes with

00:26:57   experience and and wisdom over time it's

00:27:00   it's not that you can never have fun but

00:27:02   that you should know when to have fun

00:27:05   and when it and when it's no longer fun

00:27:07   you need to get back to work yeah and I

00:27:10   think ideally the best lesson I've had

00:27:11   about that is it's trying to have

00:27:13   customer focused development in that way

00:27:15   it's like the time to do that the time

00:27:17   to solve interesting problems is to find

00:27:20   features or find apps or find ideas that

00:27:23   solving a difficult problem will make a

00:27:27   customer's life better and like the

00:27:29   intersection of those two things like a

00:27:31   really interesting technical problem and

00:27:33   a real honest need or pain point in

00:27:36   someone's life like that's where really

00:27:38   interesting and fun work happens and if

00:27:41   you can't sort of honestly say that it's

00:27:43   both interesting to build and useful for

00:27:46   a customer then you're probably not in a

00:27:49   place that is actually worth building

00:27:50   all right thanks life listening

00:27:52   everybody please tell your friends about

00:27:54   the show helps help us spread the word

00:27:56   recommend us an overcast and we'll see

00:27:59   you next week