1
00:00:03,665 --> 00:00:05,925
Leo Dion (host): Welcome to
another episode of Empower Apps.

2
00:00:06,045 --> 00:00:08,025
I'm your host, Leo Dion.

3
00:00:08,675 --> 00:00:14,155
Today, I'm joined once again
with five-timer Donnie Walls.

4
00:00:14,285 --> 00:00:16,535
Donnie, thank you for coming back.

5
00:00:16,535 --> 00:00:17,225
It's been a while.

6
00:00:18,153 --> 00:00:19,843
Donny Wals (guest): Yeah,
thanks for inviting me back.

7
00:00:19,853 --> 00:00:21,203
It's a always a pleasure to be on

8
00:00:22,203 --> 00:00:24,753
Leo Dion (host): Before we begin
what have you been up to lately?

9
00:00:26,083 --> 00:00:28,753
Donny Wals (guest): Oh, I've
been up to a bunch of things

10
00:00:28,863 --> 00:00:29,943
since the last time we spoke.

11
00:00:29,943 --> 00:00:34,273
I don't remember exactly when I was
on last time, but basically last year

12
00:00:34,273 --> 00:00:36,243
I didn't do too much of conferencing.

13
00:00:36,243 --> 00:00:40,073
I was just working on client work,
my apps, my blog, and everything.

14
00:00:40,743 --> 00:00:45,763
And then this year came around and
everything was different with AI

15
00:00:46,073 --> 00:00:47,583
suddenly eating a lot of traffic.

16
00:00:47,583 --> 00:00:51,373
So I decided to double down on
my workout tracking app which

17
00:00:51,373 --> 00:00:52,293
I've been working on a lot.

18
00:00:52,303 --> 00:00:53,253
It's called Magazine.

19
00:00:53,643 --> 00:00:55,993
I've been doing just more of client work.

20
00:00:56,683 --> 00:01:00,083
I've updated my Swift
concurrency book in the meantime.

21
00:01:00,993 --> 00:01:08,233
And yeah, mainly a lot of trying to
figure out what to do in this age of AI

22
00:01:08,233 --> 00:01:12,503
and how it will change the way I work,
how it will change the content that I

23
00:01:12,503 --> 00:01:14,043
make, the content that I want to make.

24
00:01:14,053 --> 00:01:16,493
So been thinking about that a lot as well.

25
00:01:17,443 --> 00:01:21,123
Hasn't really turned into
anything to create yet.

26
00:01:21,463 --> 00:01:23,563
But thinking is being done a lot.

27
00:01:23,683 --> 00:01:24,093
Yeah

28
00:01:26,023 --> 00:01:29,173
Leo Dion (host): So how, what
surprised you the most over the

29
00:01:29,173 --> 00:01:35,123
last year or so as far as like
where AI, how AI has affected you?

30
00:01:35,897 --> 00:01:36,347
Donny Wals (guest): Yeah.

31
00:01:36,347 --> 00:01:42,377
So it's been something that was, I think,
on my mind probably somewhere around

32
00:01:43,567 --> 00:01:50,927
late 2024, where we had Cursor, and
it became easier and easier to use AI,

33
00:01:51,847 --> 00:01:55,627
and it was still very much not great.

34
00:01:56,257 --> 00:02:00,127
But you could see that this was
something that a lot of very smart

35
00:02:00,127 --> 00:02:05,167
people were interested in, and
you could see that, that there was

36
00:02:05,207 --> 00:02:07,047
going to be a use for it, right?

37
00:02:07,047 --> 00:02:10,817
At that point, I was pretty sure that
it would impact the way that I work,

38
00:02:10,827 --> 00:02:12,537
it would impact the work that I did.

39
00:02:13,177 --> 00:02:14,747
I just had no idea how.

40
00:02:14,807 --> 00:02:19,927
And then somewhere through 2025, I feel
like things started to fade a little bit.

41
00:02:20,117 --> 00:02:22,607
People seemed to almost lose interest.

42
00:02:23,377 --> 00:02:27,357
We were just resuming work as normal,
and we had these cool tools, but

43
00:02:28,157 --> 00:02:29,887
real developers wouldn't use it.

44
00:02:29,907 --> 00:02:30,647
You know what I mean?

45
00:02:30,747 --> 00:02:32,377
So everyone's like: "Oh, it's not great.

46
00:02:32,377 --> 00:02:37,497
It doesn't do anything exactly the way I
want it to." But then, So I, I was pretty

47
00:02:37,497 --> 00:02:43,037
comfortable during that time, and then
suddenly late 2025 all these new models

48
00:02:43,037 --> 00:02:47,447
came out, and we didn't just have Cursor
as a harness, we also had Claude Code,

49
00:02:47,447 --> 00:02:52,707
we also had Codex, and all of a sudden,
almost overnight I felt like it happened

50
00:02:52,717 --> 00:02:54,787
over Christmas, over the New Year's break.

51
00:02:54,787 --> 00:02:57,947
A lot of people were off talking
to friends and family, and we all

52
00:02:57,947 --> 00:03:03,037
came back mid-January, and suddenly
nobody wanted to write code anymore,

53
00:03:03,067 --> 00:03:04,627
at least not in, in my environment.

54
00:03:04,647 --> 00:03:07,437
Everybody was like: "Okay, I'm not
writing code. I'm going to prompt it.

55
00:03:07,557 --> 00:03:11,037
I'm gonna use agents because now an
agent can work on my full project,

56
00:03:11,057 --> 00:03:13,667
and it might not be perfect code,
but it's good enough to keep it."

57
00:03:14,387 --> 00:03:16,707
And it's almost just like that.

58
00:03:16,747 --> 00:03:18,287
It was a long time coming.

59
00:03:18,967 --> 00:03:23,027
It almost felt like it might never happen,
and then suddenly it just happened.

60
00:03:23,217 --> 00:03:24,677
Agentic coding was there.

61
00:03:25,047 --> 00:03:26,657
Nobody wanted to read blogs anymore.

62
00:03:26,677 --> 00:03:28,227
Nobody wanted to read books anymore.

63
00:03:28,237 --> 00:03:31,057
Nobody wanted to learn anything
anymore other than how do I prompt

64
00:03:31,057 --> 00:03:35,017
this thing efficiently, and how do I
just make it magically do what I want?

65
00:03:35,667 --> 00:03:39,107
And so the way it impacted me was
it changed the way that I work, and

66
00:03:39,157 --> 00:03:41,777
it's really made the blog take a hit.

67
00:03:41,847 --> 00:03:43,447
It's really made the books take a hit.

68
00:03:43,637 --> 00:03:47,947
It's really hard to sell workshops now
to, to companies because they're…

69
00:03:48,327 --> 00:03:51,377
Like, nobody seems, especially for
the first five, six months of the

70
00:03:51,377 --> 00:03:55,527
year, nobody seems very interested
anymore in deeply learning something.

71
00:03:55,617 --> 00:03:58,387
Everybody just wants to
get the agent to do stuff.

72
00:04:00,251 --> 00:04:01,691
Leo Dion (host): Let's see,
where do I go with this?

73
00:04:02,031 --> 00:04:07,431
So do you think we're gonna
see a rebound at some point?

74
00:04:07,481 --> 00:04:11,111
Because I mean, at some point you
do kinda have to know how this

75
00:04:11,111 --> 00:04:12,501
stuff works behind the scenes

76
00:04:13,725 --> 00:04:15,625
Donny Wals (guest): Yeah, I'm
not exactly sure about that.

77
00:04:15,715 --> 00:04:17,055
In a way, I think so.

78
00:04:17,055 --> 00:04:22,465
It actually feels like the magic has
worn off over the past couple months,

79
00:04:22,535 --> 00:04:28,875
and a lot of people are tired of not
writing code, tired of this crazy new

80
00:04:29,415 --> 00:04:31,775
multitasking that we're all having to do.

81
00:04:31,835 --> 00:04:35,365
We're all being encouraged
by companies, by managers, by

82
00:04:35,365 --> 00:04:38,125
CTOs to spend tokens, right?

83
00:04:38,285 --> 00:04:39,475
To make sure that we

84
00:04:39,489 --> 00:04:41,939
Leo Dion (host): a lot of
pullback from that, like

85
00:04:42,003 --> 00:04:43,433
Donny Wals (guest): it's been
starting to happen, yeah.

86
00:04:43,433 --> 00:04:46,263
I was about to say the beginning
of the year was like do as

87
00:04:46,273 --> 00:04:47,703
much as you can with AI.

88
00:04:47,713 --> 00:04:52,983
We were all very much almost forced to
try and almost like multitask into the

89
00:04:52,983 --> 00:04:59,803
point where it seemed like higher-ups
and enthusiasts were almost trying to

90
00:04:59,803 --> 00:05:04,063
spend like an hour in the morning to
tell like as much agents as possible

91
00:05:04,713 --> 00:05:07,963
to perform as many tasks as they
possibly could, and then you would go

92
00:05:07,963 --> 00:05:11,123
off and do other stuff, and you'd come
back in the afternoon, and you would

93
00:05:11,153 --> 00:05:13,153
just click approve on a bunch of PRs.

94
00:05:13,843 --> 00:05:17,233
And the reality has been that's
not the way it works, right?

95
00:05:17,233 --> 00:05:21,363
Like I, I think more and more people are
just seeing okay, we're producing more

96
00:05:21,373 --> 00:05:24,693
PRs, but reviewing them is more tedious.

97
00:05:24,703 --> 00:05:25,373
It's harder.

98
00:05:25,373 --> 00:05:28,083
It takes longer if we
want to do it correctly.

99
00:05:28,083 --> 00:05:29,253
We have feedback.

100
00:05:29,263 --> 00:05:33,473
We have suggestions, but whoever put
up the PR doesn't really know how

101
00:05:33,473 --> 00:05:36,373
to properly implement the feedback
because they didn't really write

102
00:05:36,393 --> 00:05:38,003
all of the code in the first place.

103
00:05:38,533 --> 00:05:42,973
And so in the end, we're producing more,
but we're not always shipping faster.

104
00:05:43,173 --> 00:05:46,413
We're just having more PRs
sit in review for longer.

105
00:05:46,513 --> 00:05:49,693
I think that's the reality for a
lot of what I'm seeing at least

106
00:05:49,693 --> 00:05:50,803
and what I'm hearing as well.

107
00:05:51,355 --> 00:05:54,085
Leo Dion (host): That makes a lot of
sense, especially in a big company.

108
00:05:54,135 --> 00:05:54,885
Donny Wals (guest): Yeah

109
00:05:55,069 --> 00:05:56,749
Leo Dion (host): to have
human eyes on stuff.

110
00:05:57,233 --> 00:05:57,823
Donny Wals (guest): Absolutely.

111
00:05:57,823 --> 00:06:03,893
And I actually read this study as
well where for that particular company

112
00:06:04,053 --> 00:06:12,143
that they examined an AI-assisted PR
would sit in non-reviewed state, like

113
00:06:12,143 --> 00:06:15,833
waiting for review state, like two
to three times longer than other PRs.

114
00:06:16,663 --> 00:06:21,073
People would be afraid to post
feedback because that would essentially

115
00:06:21,073 --> 00:06:22,903
make them own that feedback.

116
00:06:22,903 --> 00:06:25,633
So it's "Oh, I don't agree with the
architecture here." And they were

117
00:06:25,633 --> 00:06:29,003
afraid that whoever made the PR
didn't fully support the architecture,

118
00:06:29,003 --> 00:06:31,803
so they'd be like, "Okay, well,
tell me how to do it," or "Help

119
00:06:31,813 --> 00:06:33,173
me prompt the agent how to do it."

120
00:06:33,183 --> 00:06:36,893
So they would suddenly
become part owner of that PR.

121
00:06:37,623 --> 00:06:41,733
But then once they did run through the
PRs that were made by humans and they

122
00:06:41,743 --> 00:06:47,213
had to start reviewing the AI PRs, they
would spend less time reviewing the PR

123
00:06:47,673 --> 00:06:53,513
because of complexity, because of just
the perceived, How did they put that?

124
00:06:54,063 --> 00:06:58,313
They didn't perceive that the writer put
so much effort in and so they weren't

125
00:06:58,323 --> 00:07:02,563
compelled to put in the same effort
that they would for a human-written PR.

126
00:07:03,337 --> 00:07:04,117
Leo Dion (host): Interesting

127
00:07:04,593 --> 00:07:06,603
Donny Wals (guest): yeah, it was
quite interesting to read that,

128
00:07:06,663 --> 00:07:09,903
especially because I would've expected
the review itself to take longer.

129
00:07:10,703 --> 00:07:14,753
But it seems like once, for that
company, they would put themselves to

130
00:07:14,763 --> 00:07:17,853
actually reviewing it, they actually
didn't really care about the PR so

131
00:07:17,853 --> 00:07:20,553
much, so they just approved it and "If
there's a bug, we'll have the agent

132
00:07:20,553 --> 00:07:22,333
fix it 'cause it's all AI code anyway.

133
00:07:22,333 --> 00:07:22,973
Who gives a crap?"

134
00:07:24,315 --> 00:07:24,735
Leo Dion (host): Right.

135
00:07:24,753 --> 00:07:25,573
Donny Wals (guest): quite interesting

136
00:07:26,385 --> 00:07:28,645
Leo Dion (host): I mean, a few
thoughts from me is shouldn't we be

137
00:07:28,645 --> 00:07:33,905
doing smaller PRs then so that way
they're easier to manage and review?

138
00:07:34,831 --> 00:07:35,271
Donny Wals (guest): Yeah.

139
00:07:35,861 --> 00:07:39,491
I mean, that probably helps
'cause the average PR made by an

140
00:07:39,491 --> 00:07:41,601
agent is larger than a human PR.

141
00:07:42,069 --> 00:07:46,469
I j- I just wonder, like, at what
point… if you're, right, insistent

142
00:07:46,479 --> 00:07:51,549
on using agents for everything, and
you've given it a task, and that

143
00:07:51,549 --> 00:07:56,919
task should, in theory, produce a
manageable PR, I wonder how compelled

144
00:07:57,159 --> 00:08:01,789
people would be to look at the code
the agent made, see that it implemented

145
00:08:01,809 --> 00:08:06,049
the feature, it didn't refactor half
the code base, so it's probably fine.

146
00:08:06,289 --> 00:08:09,589
I'm not sure, like, how compelled people
are to then be like, "Okay, this is kind

147
00:08:09,589 --> 00:08:16,009
of big. Let's split that up into per
screen or per first the network call,

148
00:08:16,009 --> 00:08:20,119
then the UI," or however you might have
done that as a person writing this.

149
00:08:21,189 --> 00:08:24,659
And that's also an interesting, I'm
not even sure who said it or where

150
00:08:24,659 --> 00:08:27,259
I, where exa- I read this, but I
didn't come up with this at least.

151
00:08:27,759 --> 00:08:30,999
The beauty of a human writing code
is that the human at some point

152
00:08:30,999 --> 00:08:32,469
goes, "Wait, should I be doing this?"

153
00:08:33,249 --> 00:08:33,429
Leo Dion (host): Yeah.

154
00:08:33,449 --> 00:08:34,479
Donny Wals (guest): An
agent doesn't do that.

155
00:08:34,559 --> 00:08:35,779
An agent just goes.

156
00:08:36,069 --> 00:08:39,549
"I have a task, I'm gonna go do
it." Whereas as a human, at-- when

157
00:08:39,549 --> 00:08:42,919
you're working on something, at
some point you just kind of feel

158
00:08:42,919 --> 00:08:44,619
like the vibes are not there.

159
00:08:44,669 --> 00:08:46,899
You're coding, it's this
feels like too much work.

160
00:08:46,929 --> 00:08:48,779
This feels like it's getting out of hand.

161
00:08:49,319 --> 00:08:52,899
This feels like it wasn't scoped
properly." And you stop working, and

162
00:08:52,909 --> 00:08:56,719
you go back to your manager or whatever,
and you go "Okay, maybe this ticket

163
00:08:56,759 --> 00:08:58,059
needs to be two or three tickets.

164
00:08:58,069 --> 00:09:00,609
I can work on them in parallel, but
we're gonna make three PRs out of

165
00:09:00,609 --> 00:09:02,199
this because it's too much otherwise."

166
00:09:03,139 --> 00:09:06,089
Leo Dion (host): The way okay, like I
don't know how you've been doing Maxine,

167
00:09:06,099 --> 00:09:12,489
but like the way I've been doing stuff is
kind of like I'll have a main branch, I'll

168
00:09:12,489 --> 00:09:16,929
have the version I'm releasing, and then
I'll have features, and if those features

169
00:09:16,929 --> 00:09:18,939
need to be split up, I'll split those up.

170
00:09:19,579 --> 00:09:26,319
And then like basically everything I
ever tell Claude to do is its own PR,

171
00:09:26,839 --> 00:09:32,159
and that way it's all manageable and
easy for me to look at the PR, be like…

172
00:09:32,159 --> 00:09:36,169
and quite frankly, like I think one of the
things we're afraid of but we shouldn't

173
00:09:36,169 --> 00:09:41,259
be s- we shouldn't be especially now,
is ripping out code that is excessive.

174
00:09:41,439 --> 00:09:46,049
I forgot which library I had been working
on, but I just wanted something simple

175
00:09:46,089 --> 00:09:52,319
and it gave me like fallback retries,
networking caching, all this crap that

176
00:09:52,319 --> 00:09:56,139
was just like maybe it works, maybe
it doesn't, but it's crap I have to

177
00:09:56,169 --> 00:09:58,379
maintain and I have to be responsible for.

178
00:09:58,439 --> 00:10:02,669
And it's like we should be okay with
saying no to too much code from a

179
00:10:02,809 --> 00:10:03,169
agent

180
00:10:04,057 --> 00:10:05,627
Donny Wals (guest): Yeah
I totally agree with that.

181
00:10:06,357 --> 00:10:08,877
I've been dealing with
that myself in two ways.

182
00:10:08,977 --> 00:10:10,887
One is I do the same thing you do.

183
00:10:10,927 --> 00:10:13,107
Ev-every prompt basically becomes a PR.

184
00:10:13,627 --> 00:10:16,787
Maybe there's a follow-up prompt to
clean something up, but generally

185
00:10:16,787 --> 00:10:18,427
speaking, one task is one PR.

186
00:10:18,427 --> 00:10:21,887
I have agents working in worktrees
so I can have multiple in parallel.

187
00:10:22,437 --> 00:10:26,637
And then before I tell it to make a
PR, I always tell it to do a review

188
00:10:27,187 --> 00:10:30,997
where it will scrutinize every line
of code that it added as is this

189
00:10:31,057 --> 00:10:33,297
absolutely necessary to achieve the goal?

190
00:10:33,887 --> 00:10:38,017
And basically encouraging it to
do the same result with less code.

191
00:10:38,667 --> 00:10:42,277
I always ask it like, "Is there anything
in there for backwards compatibility?

192
00:10:42,307 --> 00:10:45,167
If so, rip it out because
you're building a new feature.

193
00:10:45,167 --> 00:10:45,507
Don't be

194
00:10:45,599 --> 00:10:46,319
Leo Dion (host): Yeah.

195
00:10:46,349 --> 00:10:47,859
Oh my gosh, I get that a lot.

196
00:10:47,929 --> 00:10:50,739
I've got libraries that are
in beta and it's "Oh, you sure

197
00:10:50,739 --> 00:10:52,489
this is okay?" No, I don't care.

198
00:10:52,549 --> 00:10:53,119
Donny Wals (guest): Exactly.

199
00:10:53,119 --> 00:10:56,869
So it's and sometimes I have to point
it to compare this to main because we're

200
00:10:56,869 --> 00:11:01,169
like five commits deep and like maybe
multiple PRs stacked on top of each other.

201
00:11:01,169 --> 00:11:03,589
So it's "Oh, but you already had
this feature and we're changing

202
00:11:03,589 --> 00:11:06,229
it now, so maybe it's not a user."
But it's "No, compare it to main.

203
00:11:06,529 --> 00:11:09,399
If it's not on main, it doesn't
exist, and you're fine to break

204
00:11:09,549 --> 00:11:11,409
everything and anything you want.

205
00:11:11,799 --> 00:11:14,129
If there's anything I want
preserved, I will let you know."

206
00:11:14,561 --> 00:11:16,981
Leo Dion (host): Have you tried
to put any of this guidance in

207
00:11:17,061 --> 00:11:19,421
a Claude MD or Agents MD file?

208
00:11:19,591 --> 00:11:20,801
Donny Wals (guest):
It's in the agents file.

209
00:11:20,801 --> 00:11:24,091
I find that most of
the time it works okay.

210
00:11:24,381 --> 00:11:27,741
The problem is that it becomes
like a blanket thing, where if I

211
00:11:27,841 --> 00:11:30,691
do want backwards compatibility,
I have to be explicit about it.

212
00:11:30,701 --> 00:11:34,331
So I'm always trying to balance,
like, how annoying is it to pull it

213
00:11:34,331 --> 00:11:40,391
back on this, and how annoying is it
if it's too strict with this rule?

214
00:11:40,791 --> 00:11:41,551
Or if… Right?

215
00:11:41,551 --> 00:11:44,561
So th- that's a trade-off that I always
have to that I'm always trying to make.

216
00:11:45,491 --> 00:11:48,121
Leo Dion (host): What kind of,
So let's take one step back.

217
00:11:48,151 --> 00:11:54,491
What are you using now for your Nginx
coding, and what are you using as far as

218
00:11:54,611 --> 00:11:57,481
p- managing PRs, reviewing PRs, et cetera?

219
00:11:58,111 --> 00:11:59,381
Donny Wals (guest): So I'm using Cursor.

220
00:11:59,671 --> 00:12:01,431
It's one that I started using early on.

221
00:12:01,431 --> 00:12:02,261
I've always liked it.

222
00:12:02,761 --> 00:12:06,621
I like that it allows me to switch
models really easily and not just

223
00:12:06,621 --> 00:12:08,761
the two big players, but any model.

224
00:12:09,351 --> 00:12:13,071
And actually Composer, which is Cursor's
own model is pretty good nowadays.

225
00:12:13,231 --> 00:12:14,231
It's all I need.

226
00:12:14,971 --> 00:12:20,241
And it's super cheap compared to
the API usage for ChatGPT or or

227
00:12:20,291 --> 00:12:21,021
Leo Dion (host): How much is it?

228
00:12:21,711 --> 00:12:23,331
Donny Wals (guest): I mean, the
plan itself is really expensive.

229
00:12:23,351 --> 00:12:26,381
I'm on a $200 plan, but I
never run out of tokens.

230
00:12:26,411 --> 00:12:29,711
On a $20 one I used to run out of
tokens, but I haven't tried it with

231
00:12:29,831 --> 00:12:35,191
only Composer, 'cause Cursor subsidizes
usage with their own model, obviously,

232
00:12:35,291 --> 00:12:35,311
Leo Dion (host): Yeah.

233
00:12:35,441 --> 00:12:35,921
Donny Wals (guest): Heavily.

234
00:12:36,431 --> 00:12:39,641
If you use ChatGPT through
Cursor, it's quite expensive

235
00:12:39,641 --> 00:12:41,821
because you're paying API pricing.

236
00:12:42,225 --> 00:12:42,495
Leo Dion (host): Yep

237
00:12:43,621 --> 00:12:45,601
Donny Wals (guest): So it's
a bit of a trade-off but it's

238
00:12:45,601 --> 00:12:46,491
been working really well for me.

239
00:12:46,491 --> 00:12:50,071
I've been using it for, I think,
exclusively for six months now.

240
00:12:50,791 --> 00:12:53,861
And for my PRs I'm still just
reviewing them on GitHub.

241
00:12:54,481 --> 00:12:56,991
I am somewhat changing the
way I look at the code.

242
00:12:57,381 --> 00:13:02,791
I mainly kinda spot check it for is
this what I would expect versus is

243
00:13:02,791 --> 00:13:04,461
this what I would have written myself?

244
00:13:05,311 --> 00:13:08,021
Which has not always been great.

245
00:13:08,081 --> 00:13:09,811
I mainly do this on Magazine, by the way.

246
00:13:09,811 --> 00:13:13,231
On client work I'm still a lot more
scrutinizing, but Magazine is my

247
00:13:13,811 --> 00:13:16,981
playground essentially, where I just
wanna see how far I can push this.

248
00:13:17,431 --> 00:13:19,151
So just it's different ways of working.

249
00:13:19,161 --> 00:13:24,751
Basically Magazine is almost like… I've
almost blind merged PRs but I'm still

250
00:13:24,751 --> 00:13:28,071
not confident enough to do that, 'cause
almost every time there's a subtle bug

251
00:13:29,263 --> 00:13:30,213
Leo Dion (host): Let
me ask you a question.

252
00:13:30,293 --> 00:13:35,633
What APIs im- so you're pretty
good with I don't know, Swift data.

253
00:13:35,633 --> 00:13:37,423
You've written books about core data.

254
00:13:37,443 --> 00:13:41,193
You've written books about certain
libraries that involve reacting to

255
00:13:41,193 --> 00:13:43,083
information which we won't c- name.

256
00:13:43,453 --> 00:13:47,963
W- you've, you're quite experienced in
certain APIs and not experienced in some.

257
00:13:48,553 --> 00:13:53,383
When it comes to Maxine's work, are
there particular areas where "Yeah,

258
00:13:53,383 --> 00:13:59,253
I don't really know how this works,
and I'm just gonna let Cursor have its

259
00:13:59,427 --> 00:13:59,927
Donny Wals (guest): Oh, yeah.

260
00:14:00,517 --> 00:14:01,227
I would say half the

261
00:14:01,293 --> 00:14:02,073
Leo Dion (host): an example?

262
00:14:02,917 --> 00:14:07,277
Donny Wals (guest): so I had never
done a watch app before and so I

263
00:14:07,277 --> 00:14:10,247
basically just told it "Make me a
watch app. Here's what it needs to

264
00:14:10,247 --> 00:14:16,147
do." And like it did a decent job of
setting up, like, all the essentials,

265
00:14:16,157 --> 00:14:18,197
mainly communicating with the phone.

266
00:14:18,817 --> 00:14:20,357
'Cause like I was reading it.

267
00:14:20,517 --> 00:14:21,297
I was looking at the sample.

268
00:14:21,297 --> 00:14:23,107
I was like, "Okay, this is a lot of work.

269
00:14:23,337 --> 00:14:26,047
Leo Dion (host): Did you try my
library for watch communication?

270
00:14:26,737 --> 00:14:28,117
Donny Wals (guest): I did not, no.

271
00:14:28,371 --> 00:14:30,801
Leo Dion (host): Okay, we'll
talk about Sundial K afterwards.

272
00:14:31,047 --> 00:14:31,847
Donny Wals (guest): We'll talk about that.

273
00:14:31,917 --> 00:14:32,957
I might wanna integrate that.

274
00:14:33,607 --> 00:14:36,527
But like I just told it like, "Hey, make
me this. It needs to communicate that."

275
00:14:36,577 --> 00:14:38,377
And it just gave me a bunch of code.

276
00:14:39,117 --> 00:14:44,957
And I think the main part that I
went back and forth with was, like,

277
00:14:45,167 --> 00:14:47,237
how do we communicate data, right?

278
00:14:47,237 --> 00:14:48,347
Do we use structs?

279
00:14:48,367 --> 00:14:51,477
Do we just send Swift data objects?

280
00:14:52,047 --> 00:14:56,817
Do we send encoded messages that
aren't that are strings or whatever?

281
00:14:56,817 --> 00:15:01,107
It came up with a bunch of
ideas, and we ended up deciding

282
00:15:01,117 --> 00:15:02,457
that structs was the way to go.

283
00:15:02,457 --> 00:15:07,327
So the only place that touches my
actual database is the phone the

284
00:15:07,327 --> 00:15:12,307
watch, live activities, widgets, app
intents, they all talk to snapshots.

285
00:15:12,317 --> 00:15:17,707
So bas- every time the user does a
workout, I generate a snapshot of it that

286
00:15:17,747 --> 00:15:21,447
exists on the file system only the parts
that would be needed by other parts.

287
00:15:22,177 --> 00:15:26,287
And if, for example, an app intent
wants to communicate back to the

288
00:15:26,287 --> 00:15:29,887
watch or to the phone it will make
a snapshot, same for the watch.

289
00:15:30,017 --> 00:15:32,407
It will send a specific
message to the phone app.

290
00:15:32,987 --> 00:15:36,067
The phone app then processes it,
updates the database, and sends

291
00:15:36,127 --> 00:15:37,507
information back to the watch.

292
00:15:37,537 --> 00:15:39,117
The watch updates its UI.

293
00:15:39,687 --> 00:15:39,987
Leo Dion (host): Okay

294
00:15:40,097 --> 00:15:42,187
Donny Wals (guest): And look,
I had never done that before.

295
00:15:42,397 --> 00:15:45,427
I figured it would be a lot
of work, and I wanted it fast

296
00:15:45,427 --> 00:15:46,547
so that I could start testing.

297
00:15:47,127 --> 00:15:51,047
And it's I think it took four hours
for me to have it on my watch, on

298
00:15:51,057 --> 00:15:54,427
my phone, and to go to the gym and
actually have a first version to test.

299
00:15:55,303 --> 00:15:55,413
Leo Dion (host): Yeah.

300
00:15:55,513 --> 00:15:58,453
Tell the story you had about
the app crashing mid-workout,

301
00:15:58,543 --> 00:15:59,573
'cause that was pretty good

302
00:16:00,301 --> 00:16:00,721
Donny Wals (guest): Oh, yeah.

303
00:16:00,741 --> 00:16:04,661
That's a nice thing about Cursor also is
that they have a web interface, right?

304
00:16:04,711 --> 00:16:08,181
That sort of was a reason that
I liked it so much as well.

305
00:16:08,671 --> 00:16:12,721
And as I was testing the… I don't
remember which particular feature I

306
00:16:12,721 --> 00:16:18,351
was testing, but I was testing the app,
and I did something, and it crashed.

307
00:16:18,621 --> 00:16:22,211
And I tried it again, and I could
get it to crash a second time.

308
00:16:22,241 --> 00:16:22,881
Okay, perfect.

309
00:16:23,411 --> 00:16:24,711
I have reproduction steps.

310
00:16:24,721 --> 00:16:28,331
So I just went to cursor.com,
fired off an agent.

311
00:16:28,921 --> 00:16:32,821
I, in detail, described what I did
in the app and that it crashed.

312
00:16:32,981 --> 00:16:35,831
And luckily, I was on a TestFlight
build, so as I was typing that,

313
00:16:36,241 --> 00:16:39,001
I got an email from TestFlight
saying a user submitted feedback.

314
00:16:39,411 --> 00:16:43,641
So I had a crash report, and I just
copied that over, attached it to my

315
00:16:43,641 --> 00:16:46,491
prompt and was like, "Here's everything
that I did. Here's the crash report.

316
00:16:46,951 --> 00:16:51,751
Go figure it out." And the funny
thing is that Cursor runs on Linux,

317
00:16:51,761 --> 00:16:53,811
so it wasn't able to build my iOS app.

318
00:16:54,501 --> 00:16:57,081
So it basically just
completely went by vibes.

319
00:16:57,111 --> 00:16:59,841
It was just like, "Okay, here's what
the user told me. Here's probably what

320
00:16:59,851 --> 00:17:04,651
went wrong." And I got back home, and
a PR was sitting there waiting for me.

321
00:17:04,651 --> 00:17:06,551
Bitrise had run, had ran a build.

322
00:17:07,031 --> 00:17:08,681
It had ran my tests.

323
00:17:09,181 --> 00:17:09,811
It was all green.

324
00:17:09,821 --> 00:17:10,461
It was all good.

325
00:17:11,251 --> 00:17:15,141
And all I needed to do was install
it on my device, check that the crash

326
00:17:15,141 --> 00:17:17,011
was resolved, and it actually worked.

327
00:17:17,471 --> 00:17:20,271
There were a few minor nitpicks
that I wanted to fix in the code,

328
00:17:20,301 --> 00:17:22,071
but yeah, it was pretty good.

329
00:17:22,121 --> 00:17:25,651
Especially because it was so in the
moment no thinking of "Oh, what did

330
00:17:25,651 --> 00:17:29,261
I do exactly?" No first writing a
crash report on my phone and then

331
00:17:29,271 --> 00:17:31,081
forgetting it when I got home.

332
00:17:31,701 --> 00:17:32,691
I have that all the time, right?

333
00:17:32,691 --> 00:17:33,841
I write something down in a note.

334
00:17:34,481 --> 00:17:35,721
I go home after the gym.

335
00:17:36,081 --> 00:17:36,771
Kids are there.

336
00:17:36,841 --> 00:17:40,611
Kids need to be picked up, whatever,
and I forget all about that note until

337
00:17:40,611 --> 00:17:42,541
I've found my next bug in the gym.

338
00:17:43,101 --> 00:17:47,011
I say, "Oh, crap, I forgot about that one
thing." So sending it immediately to an

339
00:17:47,011 --> 00:17:52,621
agent and having a PR to review was…
Yeah, that was really a very cool moment

340
00:17:52,631 --> 00:17:57,261
for me to, to, "Okay, so here's how we
could be working on some of these things."

341
00:17:58,083 --> 00:17:59,483
Leo Dion (host): Do they have Swift?

342
00:17:59,593 --> 00:18:02,883
So Cursor has you can
run stuff on the web.

343
00:18:03,273 --> 00:18:04,523
Can it run Swift?

344
00:18:05,187 --> 00:18:07,407
Donny Wals (guest): I think it should
be able to install and run Swift.

345
00:18:07,407 --> 00:18:08,907
You can build your own containers.

346
00:18:09,027 --> 00:18:10,817
So if I had made all of this into

347
00:18:11,155 --> 00:18:15,555
Leo Dion (host): Cl- Claude Code doesn't
have that, so you can't even run Swift.

348
00:18:15,615 --> 00:18:21,535
So I am one who has also on occasion
coded on my phone by going into the

349
00:18:21,535 --> 00:18:25,175
Claude app and telling it to create
a PR for something I just remembered.

350
00:18:25,565 --> 00:18:29,565
So I totally get it, but like every time
I've tried to get Swift to work, it's "No,

351
00:18:29,575 --> 00:18:31,275
we can't install Swift on this server."

352
00:18:31,295 --> 00:18:33,185
It's or you can't do
like a Docker container.

353
00:18:33,185 --> 00:18:34,495
It's pretty limited right now

354
00:18:35,107 --> 00:18:35,347
Donny Wals (guest): Yeah.

355
00:18:35,377 --> 00:18:39,107
I think Cursor does allow you to
configure containers, but they launched

356
00:18:39,107 --> 00:18:44,707
an iOS app two or three days ago,
and I haven't tried it yet, but the

357
00:18:44,757 --> 00:18:48,297
app can actually connect to your
computer, and then you can run agents

358
00:18:48,317 --> 00:18:51,527
on your computer which is really nice.

359
00:18:51,577 --> 00:18:56,407
I've been running a setup with a Mac Mini
for basically just to try it, where I

360
00:18:56,407 --> 00:19:01,227
can just SSH into my Mac Mini at home,
and then instead of using the Cursor

361
00:19:01,227 --> 00:19:04,847
website, I can just fire up a Cursor
agent on the Mac Mini I have at home.

362
00:19:05,257 --> 00:19:08,697
Which is also quite nice 'cause then
I have the simulator and, Actually,

363
00:19:08,697 --> 00:19:14,167
just last weekend, I was at a festival
and they didn't have offline access

364
00:19:14,167 --> 00:19:17,457
for their timetable thing, and the
internet was, like, non-existent there.

365
00:19:18,367 --> 00:19:24,707
So when I got back to my hotel, I
told Cursor on the Mac Mini to make

366
00:19:24,707 --> 00:19:26,597
me an app based on the website.

367
00:19:26,677 --> 00:19:28,117
I just gave the URL for the timetable.

368
00:19:28,757 --> 00:19:33,427
And since I wouldn't be able to
install it 'cause I was not with my

369
00:19:33,697 --> 00:19:37,607
MacBook at that time I did have it
close, but I wasn't… I was at the

370
00:19:37,617 --> 00:19:39,247
breakfast thing so I told it that.

371
00:19:39,247 --> 00:19:43,127
I was like, "Okay, take these
screenshots of every state of the app

372
00:19:43,397 --> 00:19:45,807
and put them on the GitHub README.

373
00:19:45,817 --> 00:19:47,237
Make me a repo and everything.

374
00:19:47,717 --> 00:19:49,527
Put the screenshots there.

375
00:19:49,667 --> 00:19:53,067
Build me the app." And then
basically just on those screenshots,

376
00:19:53,097 --> 00:19:55,137
I iterated for a bit. I was like,
"Okay, this needs to change.

377
00:19:55,137 --> 00:19:56,027
That needs to change."

378
00:19:56,475 --> 00:19:58,535
Leo Dion (host): Wait, th- where
were you when you were doing this?

379
00:19:59,057 --> 00:20:01,497
Donny Wals (guest): I was having
breakfast with my wife at the hotel.

380
00:20:01,497 --> 00:20:03,187
We were talking about how
annoying it was that we couldn't

381
00:20:03,197 --> 00:20:04,687
do the timetable the day before.

382
00:20:05,245 --> 00:20:07,475
Leo Dion (host): W- what did
Mrs. Walls think about this?

383
00:20:07,857 --> 00:20:08,847
Donny Wals (guest): She
thought it was amazing.

384
00:20:08,907 --> 00:20:12,247
She was so happy because she was very
annoyed at, like I was, with the lack

385
00:20:12,247 --> 00:20:14,956
of timetable at the venue itself.

386
00:20:14,976 --> 00:20:18,227
So we were just trying to figure out,
like, how should this thing work, and

387
00:20:18,227 --> 00:20:21,086
just talking to the agent, and then
we go back to the hotel room, plug

388
00:20:21,087 --> 00:20:24,016
in our phones, install the app, and
we used it for the next two days.

389
00:20:24,026 --> 00:20:24,836
It was amazing.

390
00:20:25,466 --> 00:20:26,926
And I haven't even seen the code.

391
00:20:27,166 --> 00:20:28,396
I didn't even check anything.

392
00:20:28,517 --> 00:20:30,796
Just as long as it worked,
installed on my phone, solved

393
00:20:30,796 --> 00:20:32,106
my problem, I was happy with it

394
00:20:33,106 --> 00:20:33,456
Leo Dion (host): Yeah.

395
00:20:33,646 --> 00:20:35,526
Yeah I have a few Mac Minis.

396
00:20:35,596 --> 00:20:37,956
I need to do that and
take advantage of that.

397
00:20:37,966 --> 00:20:42,136
I haven't gotten to that part
yet, but that makes total sense.

398
00:20:42,676 --> 00:20:45,626
I wanted to hop back and
talk about architecture.

399
00:20:45,636 --> 00:20:48,386
Is there anything you're changing as
far as your architecture and your…

400
00:20:49,456 --> 00:20:53,716
let's talk Maxine, but also let's
talk your other jobby-job stuff.

401
00:20:54,376 --> 00:20:57,716
Is there a way you're changing the way
you're architecting your apps in any way?

402
00:20:58,716 --> 00:21:00,356
Donny Wals (guest): Not necessarily.

403
00:21:01,816 --> 00:21:06,636
I'm mostly less concerned about
repetitive code and boring stuff.

404
00:21:07,346 --> 00:21:11,006
Like when I would write code by hand,
I would be writing the same kind of

405
00:21:11,006 --> 00:21:14,556
thing like over and over, and it's 99%
the same, but it's slightly different.

406
00:21:14,916 --> 00:21:17,016
I would start thinking about
like, how do I abstract that?

407
00:21:17,086 --> 00:21:19,486
Like, how do I make it so that
I don't have to repeat this

408
00:21:19,536 --> 00:21:21,386
little dance every single time?

409
00:21:21,996 --> 00:21:28,326
And I think more often than not, that
would actually lead to like clever code

410
00:21:28,336 --> 00:21:32,517
where it's like it it's 99% the same,
so you still have to account for the

411
00:21:32,517 --> 00:21:36,806
differences, but most things are the
same, so you can come up with something

412
00:21:36,806 --> 00:21:38,656
with generics and do smart stuff.

413
00:21:39,196 --> 00:21:39,956
And,

414
00:21:39,990 --> 00:21:41,000
Leo Dion (host): Ah, I get it

415
00:21:41,116 --> 00:21:44,516
Donny Wals (guest): almost always
that sort of bites you in the end.

416
00:21:45,276 --> 00:21:50,646
And I do like that when I tell an agent to
do the boring thing, it will just do it.

417
00:21:51,006 --> 00:21:55,066
And yes, there is some repetitive
pieces of code, but it's repetitive

418
00:21:55,076 --> 00:21:57,746
not because it's doing the
same thing every single time.

419
00:21:57,746 --> 00:22:00,426
It's just repetitive because
that's just the way it is.

420
00:22:01,147 --> 00:22:04,077
Leo Dion (host): I think that's
one of those over optimization

421
00:22:04,107 --> 00:22:05,787
things that developers do.

422
00:22:05,797 --> 00:22:08,267
We hear don't repeat
yourself, the DRY method.

423
00:22:08,767 --> 00:22:14,337
And we like I think it's been
overdone because like I think until

424
00:22:14,337 --> 00:22:20,516
you g- have like several copies of
something it's not worth refactoring

425
00:22:20,556 --> 00:22:23,746
into like you said, being clever
with generics and protocols and

426
00:22:23,967 --> 00:22:24,507
Donny Wals (guest): Yeah.

427
00:22:24,557 --> 00:22:25,317
And especially

428
00:22:25,367 --> 00:22:28,256
Leo Dion (host): I was just gonna say,
it also depends if you're coding for

429
00:22:28,256 --> 00:22:30,287
an app or coding for developers too

430
00:22:31,053 --> 00:22:32,433
Donny Wals (guest): Yeah, absolutely.

431
00:22:32,903 --> 00:22:38,383
And it's also when, like, when
something is the same because it's

432
00:22:38,453 --> 00:22:42,493
doing literally the exact same thing
over and over again, or if it's the

433
00:22:42,493 --> 00:22:46,963
same just because it happens to do the
same thing, if you know what I mean.

434
00:22:46,993 --> 00:22:47,233
Leo Dion (host): Yep.

435
00:22:47,523 --> 00:22:48,433
I know exactly what

436
00:22:48,562 --> 00:22:51,703
Donny Wals (guest): like d- decoding
JSON, it feels so repetitive.

437
00:22:51,742 --> 00:22:55,052
It's the same thing over and over and
every time you do it by hand, it's

438
00:22:55,052 --> 00:22:56,893
like it's screaming for an abstraction.

439
00:22:57,692 --> 00:23:03,523
Whereas, like, when you're done and
six months go by, probably all of these

440
00:23:03,523 --> 00:23:07,262
objects will have diverged in subtle
ways and they're not exactly the same.

441
00:23:07,882 --> 00:23:10,783
And so even though the initial
writing was incredibly boring and

442
00:23:10,813 --> 00:23:14,462
repetitive, it wasn't like you did
the same thing over and over again.

443
00:23:14,512 --> 00:23:16,333
It's just it was kinda the same thing.

444
00:23:17,411 --> 00:23:17,661
Leo Dion (host): Yep

445
00:23:18,303 --> 00:23:19,183
Donny Wals (guest): so yeah.

446
00:23:19,183 --> 00:23:21,383
I like that an agent
doesn't care about that.

447
00:23:21,383 --> 00:23:24,473
It'll just do whatever you told it to,
and it doesn't care about abstractions.

448
00:23:24,503 --> 00:23:27,823
The downside, on the other hand,
is that it doesn't realize when an

449
00:23:27,833 --> 00:23:29,523
abstraction would be a good idea.

450
00:23:30,323 --> 00:23:35,013
So for example, with Magazine, I have
a lot of places where I show weights,

451
00:23:35,053 --> 00:23:37,623
and I convert from pounds to kilograms.

452
00:23:37,673 --> 00:23:38,583
Actually, the other way around.

453
00:23:38,903 --> 00:23:43,063
I store everything in kilograms, and
sometimes I present pounds for US folks.

454
00:23:43,613 --> 00:23:44,563
And,

455
00:23:44,979 --> 00:23:45,259
Leo Dion (host): way.

456
00:23:45,339 --> 00:23:46,149
Anyways, go ahead

457
00:23:46,173 --> 00:23:47,013
Donny Wals (guest): the wrong… Yeah.

458
00:23:47,703 --> 00:23:51,893
There's just a couple places where
we have to show labels for things,

459
00:23:52,173 --> 00:23:57,823
and an AI will just happily reinvent
the same helper or reinvent the same

460
00:23:57,823 --> 00:24:01,693
string interpolation every single
time, where I do have to tell it "Hey,

461
00:24:01,693 --> 00:24:03,253
look, you know what we really need?

462
00:24:03,693 --> 00:24:08,073
We need a unified way to just ask
the weight data object for a display

463
00:24:08,073 --> 00:24:11,683
weight and then use that everywhere
instead of figuring out how to

464
00:24:11,683 --> 00:24:13,943
display it locally every single time."

465
00:24:14,743 --> 00:24:17,313
Leo Dion (host): It seems I mean, you
could have both issues with an agent

466
00:24:17,313 --> 00:24:22,803
where it over-abstracts as well, and I
think the issue with repeating usually

467
00:24:22,803 --> 00:24:27,903
is just a simple context window issue
of there's just so much code that

468
00:24:27,903 --> 00:24:31,583
it's like har- it's like difficult
for it to even know that existing

469
00:24:31,583 --> 00:24:33,423
code already exists somewhere in your

470
00:24:33,453 --> 00:24:33,793
app.

471
00:24:34,663 --> 00:24:38,803
So yeah, that's usually the case
with repeating code is like you need

472
00:24:38,803 --> 00:24:42,933
somewhere Claude MD or whatever that
says, "Hey, if you ever need to do

473
00:24:42,933 --> 00:24:45,943
this is what you need to do," and
save it in the memory somewhere.

474
00:24:46,739 --> 00:24:47,219
Donny Wals (guest): Yes.

475
00:24:47,219 --> 00:24:50,449
I think you're touching on a really
interesting point there as well, where

476
00:24:51,479 --> 00:24:56,499
it's possibly even more important than
before to kind of know your way around

477
00:24:56,509 --> 00:24:58,019
the code base that you're working on.

478
00:24:58,939 --> 00:25:03,199
Because you… The better you
are at telling the agent examples

479
00:25:03,389 --> 00:25:07,139
of what you've done before, the
better the output's going to be.

480
00:25:07,159 --> 00:25:10,589
'Cause if you just let it run freely,
it might never discover that you've

481
00:25:10,759 --> 00:25:15,179
done the exact same thing mostly or
solved the exact same problem before.

482
00:25:15,389 --> 00:25:19,569
And so it will come up with its own way to
do it, and it might not be the right way.

483
00:25:19,569 --> 00:25:23,469
And then nudging it to do it the right
way without telling it how it was

484
00:25:23,499 --> 00:25:25,309
done before is really frustrating.

485
00:25:25,939 --> 00:25:27,829
So if you can just tell it
"Hey, look at this file.

486
00:25:27,839 --> 00:25:30,049
We have helpers for all the weight stuff.

487
00:25:30,679 --> 00:25:35,879
If there's anything missing, add a new
function using the exact same sort of API

488
00:25:35,889 --> 00:25:42,939
styling, and make sure that you never ever
do inline conversion of weights." If you

489
00:25:42,939 --> 00:25:47,829
can add that to your agent file or to your
prompt if it's not relevant enough for the

490
00:25:47,829 --> 00:25:53,199
entire file, then yeah, that's great, and
it's going to do a much, much better job

491
00:25:53,999 --> 00:25:57,299
Leo Dion (host): Isn't there like a
measurements API that Apple provides?

492
00:25:58,273 --> 00:25:59,003
Donny Wals (guest): There is,

493
00:25:59,429 --> 00:26:02,729
Leo Dion (host): was it using that or
was it doing its own or what exactly was

494
00:26:02,735 --> 00:26:06,035
Donny Wals (guest): So it's basically
because I wasn't using measurements

495
00:26:06,075 --> 00:26:08,995
I started building this thing
without knowing that it existed.

496
00:26:09,515 --> 00:26:13,565
So I just have a multiplier for
kilograms to, to pounds and that's it.

497
00:26:14,565 --> 00:26:15,085
It's super

498
00:26:15,153 --> 00:26:18,203
Leo Dion (host): that… Yeah, but
we need that practical measurements

499
00:26:18,203 --> 00:26:20,233
book in the next year or two.

500
00:26:20,233 --> 00:26:20,773
Donny Wals (guest): I guess so.

501
00:26:20,773 --> 00:26:21,273
I should probably

502
00:26:21,393 --> 00:26:23,353
Leo Dion (host): It'd be like
a pamphlet, but still, you

503
00:26:23,353 --> 00:26:24,573
know, it wouldn't be too bad

504
00:26:25,209 --> 00:26:30,799
Donny Wals (guest): I mean, just knowing
how to store stuff and how to normalize

505
00:26:30,799 --> 00:26:32,629
it in general is a really good idea.

506
00:26:32,799 --> 00:26:37,069
Like storing currency and stuff,
I've seen so many people mess that up

507
00:26:37,221 --> 00:26:39,641
Leo Dion (host): what are some
tips you have for people who are

508
00:26:39,641 --> 00:26:42,721
just getting into Nginx coding?

509
00:26:42,781 --> 00:26:46,001
Like I say, like context window
management is still, I think,

510
00:26:46,001 --> 00:26:48,571
important in some ways, I think.

511
00:26:48,621 --> 00:26:53,381
Yeah, just being able to document stuff
properly so it knows how things work.

512
00:26:53,941 --> 00:26:55,451
What are some other tips you might have?

513
00:26:56,269 --> 00:26:58,749
Donny Wals (guest): So just I just
want to reiterate the documenting.

514
00:26:58,989 --> 00:27:03,069
Like having an agents file or a claude.md
or I think Gemini uses gemini.md or

515
00:27:03,069 --> 00:27:05,749
whatever your agent of choosing uses.

516
00:27:06,199 --> 00:27:07,639
Make sure you have one of those.

517
00:27:07,789 --> 00:27:10,749
It helps your agent navigate
your code base, make sure that

518
00:27:10,749 --> 00:27:13,399
it contains the important parts.

519
00:27:13,419 --> 00:27:16,219
Tell it, like, where
to find certain things.

520
00:27:16,799 --> 00:27:21,659
And a nice trick that you can actually
use is you can also nest them.

521
00:27:22,079 --> 00:27:26,919
So you can have an agents.md file at
your root or a claude.md, and then

522
00:27:27,109 --> 00:27:30,269
if you have your folder structure,
like for example, like your models,

523
00:27:30,269 --> 00:27:33,689
your networking, your UI, and then
per, like in UI you have features.

524
00:27:34,309 --> 00:27:39,199
Every folder can have its own
agents.md or its own claude.md and

525
00:27:39,213 --> 00:27:43,013
Leo Dion (host): also have a .Claude
folder in the root, for instance, I

526
00:27:43,013 --> 00:27:46,293
don't know how the other ones do it,
where you can provide even more general

527
00:27:46,293 --> 00:27:48,503
documentation to guide the agent

528
00:27:49,483 --> 00:27:49,873
Donny Wals (guest): Exactly.

529
00:27:49,873 --> 00:27:51,643
A cursor has something similar as well.

530
00:27:52,013 --> 00:27:55,093
But just the fact that you can stack them
and then do progressive disclosure is

531
00:27:55,093 --> 00:27:59,483
really useful, because that means that you
can keep your root agents file relatively

532
00:27:59,483 --> 00:28:03,543
small, and then the agent can just
discover what it needs to find as it goes.

533
00:28:03,573 --> 00:28:05,353
Great way to manage your context window.

534
00:28:06,093 --> 00:28:11,203
Also, I have a sort of file that
my agent has to maintain on its

535
00:28:11,233 --> 00:28:12,723
own, which I call agent notes.

536
00:28:12,733 --> 00:28:18,113
So in my agent's file, I tell it that it
must, for every correction that I make or

537
00:28:18,113 --> 00:28:22,703
every time I tell it to always or never
do something, it must add a line to agent

538
00:28:22,723 --> 00:28:27,543
notes where it will teach itself what
to do, and then it loads that as rules

539
00:28:27,645 --> 00:28:28,715
Leo Dion (host): I like that a lot.

540
00:28:28,755 --> 00:28:28,905
Do

541
00:28:29,103 --> 00:28:29,393
Donny Wals (guest): 'cause

542
00:28:29,435 --> 00:28:31,765
Leo Dion (host): that file
through the whole process?

543
00:28:32,075 --> 00:28:35,235
Do you ever, like, when you merge
it, We'll, we can get into worktrees

544
00:28:35,275 --> 00:28:38,205
later, but then how do you deal
with merge conflicts with that or

545
00:28:38,483 --> 00:28:39,373
Donny Wals (guest): You keep everything.

546
00:28:39,383 --> 00:28:40,883
So everything it writes down is valid.

547
00:28:40,893 --> 00:28:44,233
So if there's a merge conflict, you
just resolve it by keeping both changes,

548
00:28:44,643 --> 00:28:46,243
'cause it never changes an existing line.

549
00:28:46,273 --> 00:28:48,353
It just, it's just, like appending.

550
00:28:48,709 --> 00:28:49,039
Leo Dion (host): right,

551
00:28:49,129 --> 00:28:51,279
Donny Wals (guest): so also like
conflicts, I don't think I've ever had a,

552
00:28:51,849 --> 00:28:55,899
an actual conflict on it 'cause Git will
figure out like nothing changed the same

553
00:28:55,899 --> 00:28:57,359
line, it's just everybody adding stuff.

554
00:28:58,209 --> 00:29:00,739
But then every once in a while I look
at it and I go "Okay, so there's a

555
00:29:00,739 --> 00:29:03,669
bunch of stuff there," and I'll just
tell the agent like, "Okay, find me

556
00:29:03,669 --> 00:29:05,819
like the general lessons in there.

557
00:29:05,829 --> 00:29:10,069
Find me the overarching rules
and update your agent's file so

558
00:29:10,097 --> 00:29:10,637
Leo Dion (host): Oh, I love

559
00:29:10,839 --> 00:29:13,849
Donny Wals (guest): now matches that."
And then ev- every month or so, like

560
00:29:13,849 --> 00:29:17,509
I end up with a clean agent notes and
it's so much better than trying to

561
00:29:17,509 --> 00:29:22,009
remember because sometimes you have a
session where you have to correct it

562
00:29:22,009 --> 00:29:25,669
like 10 times on the exact same thing
and it feels so important to add to your

563
00:29:25,669 --> 00:29:29,519
agent's file, but it turns out it was
just the agent having a bad day and it

564
00:29:29,529 --> 00:29:31,649
never again messes that one thing up.

565
00:29:32,189 --> 00:29:34,689
And other times it feels like it's
not such a big deal, but you've

566
00:29:34,689 --> 00:29:37,749
corrected the agent like 10 times
over the course of a month and it

567
00:29:37,759 --> 00:29:39,199
was always like a small, tiny thing.

568
00:29:39,669 --> 00:29:43,409
But then you see like the same thing
in the agent notes file or variations

569
00:29:43,409 --> 00:29:44,839
of it, and it's "Oh, hold on.

570
00:29:45,629 --> 00:29:49,419
I'm actually very often telling it
to do something in a specific way.

571
00:29:50,039 --> 00:29:55,459
So maybe we should, you know, make sure
that we generalize a nice rule out of this

572
00:29:55,549 --> 00:29:57,199
so that it always does it the right way."

573
00:29:58,149 --> 00:30:01,409
Leo Dion (host): So what, do you ever
go through it and clean it, not clean

574
00:30:01,409 --> 00:30:02,459
it up, but you know what I mean.

575
00:30:02,519 --> 00:30:04,399
Like 'cause it's just
gonna grow continually.

576
00:30:04,429 --> 00:30:06,799
Do you ever like you just
keep them all in there?

577
00:30:06,799 --> 00:30:08,879
Like it's gonna end up
getting big pretty quick

578
00:30:09,209 --> 00:30:11,489
Donny Wals (guest): Yeah so every once in
a while I'll tell the agent to go through

579
00:30:11,489 --> 00:30:13,079
it and then update the agent's file.

580
00:30:13,079 --> 00:30:16,479
And in the beginning it got
really big every single time.

581
00:30:16,569 --> 00:30:21,029
And as time goes on, it gets smarter
about what I want and the way I

582
00:30:21,279 --> 00:30:21,899
Leo Dion (host): Very good.

583
00:30:22,139 --> 00:30:22,809
Very clever

584
00:30:23,339 --> 00:30:26,599
Donny Wals (guest): almost… Now
it adds maybe two lines in a month.

585
00:30:26,769 --> 00:30:31,099
And almost always those are just
one-time things where the agent was

586
00:30:31,099 --> 00:30:34,919
just having a bad day or sometimes even
I look back at those and "Oh yeah, I

587
00:30:34,919 --> 00:30:38,169
was really not setting the agent up
for success, I think, on that day."

588
00:30:38,169 --> 00:30:41,859
I was just very vague and very changing
my mind all the time trying to work

589
00:30:41,859 --> 00:30:43,749
with an 80% full context window.

590
00:30:43,749 --> 00:30:45,439
Of course you're gonna get bad results.

591
00:30:45,569 --> 00:30:47,489
And then I'll just delete
those lines by myself.

592
00:30:47,509 --> 00:30:51,539
"Okay, fine. We don't want this."
Another one that I use that's

593
00:30:51,579 --> 00:30:55,559
also like a self-learning thing
is a skill called Grill with Docs.

594
00:30:56,343 --> 00:30:56,913
Leo Dion (host): Okay

595
00:30:57,139 --> 00:31:00,099
Donny Wals (guest): from a skill called
Grill Me, and now it's Grill with Docs.

596
00:31:00,109 --> 00:31:03,939
So what it does is every time you
prompt it the Grill part of it

597
00:31:03,939 --> 00:31:05,199
is actually like really basic.

598
00:31:05,209 --> 00:31:10,799
It basically says, "Analyze what I
say, scrutinize every part of it, keep

599
00:31:10,799 --> 00:31:14,399
asking questions until we mutually
agree on what the feature actually is.

600
00:31:14,769 --> 00:31:15,819
Do not make assumption.

601
00:31:15,879 --> 00:31:20,639
Ask a question for literally everything
you want to do." And it's quite tedious

602
00:31:20,639 --> 00:31:23,789
in the beginning especially 'cause
it'll ask you like the dumbest things.

603
00:31:24,259 --> 00:31:27,679
But in a way that it feels dumb to
you, but at the same time it's okay,

604
00:31:27,679 --> 00:31:32,419
so you're going to assume that when I
said move the button to the top, you

605
00:31:32,419 --> 00:31:34,669
assumed that you meant set Y to zero.

606
00:31:35,099 --> 00:31:38,979
Which might not have been true if
I flipped the coordinate system

607
00:31:39,079 --> 00:31:41,909
or I might have meant to move
it to 20 points or whatever.

608
00:31:42,319 --> 00:31:45,829
So it'll ask "What do you mean by
top? What do you mean by this?" And

609
00:31:45,949 --> 00:31:49,189
so when it was just a Grill Me doc,
it would do that every single time.

610
00:31:49,289 --> 00:31:54,019
Now, the guy that wrote it introduced
a new skill called Grill with Docs, and

611
00:31:54,019 --> 00:31:55,769
that looks for a file called context.md.

612
00:31:55,819 --> 00:32:02,069
And as it asks these questions, it
will find out like what is the specific

613
00:32:02,639 --> 00:32:04,619
terminology that you use for your app?

614
00:32:04,629 --> 00:32:09,319
What is the specific way that you refer
to things in your natural language?

615
00:32:09,669 --> 00:32:12,599
What is it-- what are certain--
What's the main color in your app?

616
00:32:12,629 --> 00:32:16,279
When you say, "Use the main color,"
it has to go and find a variable

617
00:32:16,289 --> 00:32:17,579
called main color every time.

618
00:32:18,079 --> 00:32:22,679
So when it finds things like that, it
goes "Okay, let's add that to context.md."

619
00:32:23,389 --> 00:32:28,189
And so context.md then becomes part
of what Grill with Docs loads as it

620
00:32:28,189 --> 00:32:30,719
starts deciding what the feature is.

621
00:32:31,239 --> 00:32:34,249
And as time goes by, it becomes
smarter and smarter, and it

622
00:32:34,309 --> 00:32:37,609
understands you and your app and
your field of business much better.

623
00:32:38,349 --> 00:32:40,029
And so I use that paired with Plan Mode.

624
00:32:40,039 --> 00:32:42,909
So basically it's like I go to
Plan Mode in Cursor, I use Grill

625
00:32:42,909 --> 00:32:46,479
with Docs, I tell it what I
want, I get a bunch of questions.

626
00:32:47,059 --> 00:32:48,779
And sometimes it's really smart about it.

627
00:32:48,779 --> 00:32:52,639
It's just the other day I told it
when I finished the last set on my

628
00:32:52,639 --> 00:32:59,049
watch and I log the set and I have
nothing else to log in my plan, it

629
00:32:59,049 --> 00:33:00,749
will suggest me to end the workout.

630
00:33:00,829 --> 00:33:01,699
I don't want that.

631
00:33:02,079 --> 00:33:04,209
I want it to allow me to add another set.

632
00:33:04,959 --> 00:33:08,329
And then it was like, "You know what?
You actually have this flow throughout

633
00:33:08,329 --> 00:33:13,659
the watch where you planned three sets of
an exercise, you press next, next, next,

634
00:33:14,499 --> 00:33:19,029
and then you go into the next exercise
immediately. Don't you want a step there

635
00:33:19,029 --> 00:33:20,959
as well so that you can add another set?"

636
00:33:20,959 --> 00:33:23,569
It's "Wow, I didn't actually think
of that," 'cause it never annoyed

637
00:33:23,639 --> 00:33:24,769
me, but you're absolutely right.

638
00:33:25,569 --> 00:33:31,009
So that's… Yeah it's for those kinds
of things it's really good 'cause it…

639
00:33:31,009 --> 00:33:34,969
it becomes that annoying developer in
the sprint planning that asks a question

640
00:33:34,969 --> 00:33:37,229
for every single sentence in a ticket.

641
00:33:37,229 --> 00:33:40,679
But in the end, they're the
ones that ship without no bugs.

642
00:33:41,149 --> 00:33:44,939
They're the ones that just ship exactly
what was meant be, to be shipped

643
00:33:44,969 --> 00:33:46,529
because they didn't assume anything.

644
00:33:46,839 --> 00:33:49,419
And 90% of the time the
assumption is correct, right?

645
00:33:49,419 --> 00:33:52,169
So the grill scale basically tells
you "I would recommend you do

646
00:33:52,169 --> 00:33:53,469
this," or, "I would assume this."

647
00:33:53,489 --> 00:33:53,829
It's "Yep,

648
00:33:53,889 --> 00:33:54,219
Leo Dion (host): yeah.

649
00:33:54,309 --> 00:33:56,169
Donny Wals (guest): But every once
in a while it's like, "Oh, hold up.

650
00:33:56,599 --> 00:33:59,159
That's a good idea," or, "I didn't
think of that," or, "That's not what

651
00:33:59,159 --> 00:34:03,929
I meant," or, "That's gonna break
something." So highly recommend that

652
00:34:04,507 --> 00:34:05,937
Leo Dion (host): You were just
talking about sprints and stuff.

653
00:34:05,937 --> 00:34:10,467
What are you using for managing
tasks or issues or sprints and stuff?

654
00:34:11,027 --> 00:34:12,237
Especially when it comes to Maxine

655
00:34:13,081 --> 00:34:15,061
Donny Wals (guest): oh I went
through a whole cycle with that.

656
00:34:15,101 --> 00:34:17,311
So I first set up GitHub projects, right?

657
00:34:17,341 --> 00:34:18,681
Where I made tickets every time.

658
00:34:19,331 --> 00:34:24,291
The problem was it was a lot of friction
for me to make tickets because it's the

659
00:34:24,291 --> 00:34:27,751
kind of app where I can test it at my
desk for hours and hours, but I have

660
00:34:27,751 --> 00:34:30,481
no idea how it works until I actually
go to the gym and try to use it.

661
00:34:31,131 --> 00:34:35,401
So I, I have to go out and use it to
actually know does this truly work?

662
00:34:35,441 --> 00:34:36,281
Does this feel right?

663
00:34:36,281 --> 00:34:40,931
Does this look right in the context of,
you know, me being sweaty, me being busy?

664
00:34:41,851 --> 00:34:44,691
So every time I found an issue,
I would have to go to GitHub,

665
00:34:44,761 --> 00:34:46,201
which on my phone, I don't know.

666
00:34:46,321 --> 00:34:50,391
The app's fine, but I don't like trying
to navigate GitHub issues on my phone.

667
00:34:50,391 --> 00:34:53,701
It feels like too much effort, especially
if you want to write down a quick

668
00:34:53,701 --> 00:34:55,241
line of something you didn't like.

669
00:34:55,639 --> 00:34:56,479
Leo Dion (host): Yeah, 100%.

670
00:34:57,651 --> 00:34:58,921
Donny Wals (guest): So I had that.

671
00:34:58,921 --> 00:35:01,791
I was like, "Okay, that might be overkill,
the project set up," 'cause like it…

672
00:35:01,841 --> 00:35:03,701
I was reluctant to write things down.

673
00:35:03,701 --> 00:35:05,396
I would just write down in my notes app.

674
00:35:05,466 --> 00:35:08,046
Okay they'll just copy it
over later, which I never did.

675
00:35:08,696 --> 00:35:11,996
Then I went to Notion, which I
still use every once in a while.

676
00:35:11,996 --> 00:35:16,856
I was like, "Maybe Notion is a bit more
lightweight." It was pretty much the same

677
00:35:16,856 --> 00:35:19,046
thing as GitHub, like just as annoying.

678
00:35:19,346 --> 00:35:22,816
Also, the Notion mobile app isn't
that great in my experience.

679
00:35:22,826 --> 00:35:27,716
It's fine, but it's not good for
doing like ticket-based stuff.

680
00:35:28,168 --> 00:35:28,568
Leo Dion (host): Great

681
00:35:28,896 --> 00:35:33,606
Donny Wals (guest): Then I decided
that note list that I had, like

682
00:35:33,606 --> 00:35:36,066
just Arraycast note, was fine.

683
00:35:36,256 --> 00:35:39,566
So it's just everything I wanna
do is a line in that notes thing.

684
00:35:40,186 --> 00:35:41,806
And when I do it, I just remove it.

685
00:35:42,016 --> 00:35:47,296
And basically what I try to do is if I
write down a problem now as I'm working

686
00:35:47,296 --> 00:35:51,826
out, I either just feed it to an agent
directly and I don't even make a note,

687
00:35:52,436 --> 00:35:55,436
or if it's more of a feature I want
to think through, I start writing a

688
00:35:55,436 --> 00:35:56,936
prompt that I would give to an agent.

689
00:35:57,536 --> 00:36:01,276
And it becomes like this whole couple
sentences on what I have in mind.

690
00:36:01,936 --> 00:36:04,936
And then I go back to
it when I'm at my desk.

691
00:36:05,416 --> 00:36:06,326
And that's kind of it.

692
00:36:06,336 --> 00:36:09,176
I don't really have a ticket
system or an issue tracker.

693
00:36:09,850 --> 00:36:14,940
Leo Dion (host): There's task tools out
there, like Task Manager and SpecKit

694
00:36:15,000 --> 00:36:19,740
and stuff, and I always have just been
going back to just doing GitHub issues

695
00:36:20,320 --> 00:36:23,690
rather… 'Cause I don't like the idea
of keeping a bunch of markdown files

696
00:36:23,690 --> 00:36:28,150
for every single issue and doing that
as far as like planning things out.

697
00:36:28,210 --> 00:36:33,950
And then, yeah, I just use milestones and
GitHub issues as far as that's concerned,

698
00:36:33,950 --> 00:36:37,940
and then make sure that Claude knows
how to use the GitHub CLI so it can

699
00:36:37,940 --> 00:36:39,820
just create the issue for me every time.

700
00:36:40,240 --> 00:36:42,230
And then whenever I have
time to go back to it, I will

701
00:36:43,154 --> 00:36:43,524
Donny Wals (guest): Yeah.

702
00:36:43,744 --> 00:36:44,804
Yeah, I mean, that works.

703
00:36:44,864 --> 00:36:46,104
I use it on other projects.

704
00:36:46,104 --> 00:36:49,014
It's just for this particular one
because in most of my bug filing

705
00:36:49,014 --> 00:36:53,174
and reporting and coming up with
features happens in the gym.

706
00:36:53,174 --> 00:36:55,354
It's for some reason
Notes app just works best

707
00:36:55,404 --> 00:36:56,614
Leo Dion (host): that
makes a lot of sense.

708
00:36:56,994 --> 00:36:57,394
Yeah.

709
00:36:58,074 --> 00:37:02,564
One thing I wanted to mention before we
switch topics that you kind of went into

710
00:37:03,114 --> 00:37:08,924
is with a lot of this stuff, you can use
these tools to help you with this stuff.

711
00:37:09,414 --> 00:37:13,864
So if you're like, "Hey I need a prompt,"
you know, it can write the prompt for

712
00:37:13,864 --> 00:37:15,314
you and you can help write the prompt.

713
00:37:15,334 --> 00:37:20,064
If you need help creating your agents
file, your context file, in a lot

714
00:37:20,064 --> 00:37:25,094
of these cases, the, these tools
can help you with those items, I

715
00:37:25,094 --> 00:37:26,984
guess is what I'm trying to say.

716
00:37:27,704 --> 00:37:30,934
And yeah, like it'll be freely
like, "Yeah, we can edit your

717
00:37:31,314 --> 00:37:34,834
agents.md so we know about this
context file," or whatever it is.

718
00:37:35,264 --> 00:37:36,594
It's usually pretty good about that

719
00:37:37,542 --> 00:37:38,322
Donny Wals (guest): Absolutely, yeah.

720
00:37:38,382 --> 00:37:40,962
I use it a lot for those kinds of things

721
00:37:42,444 --> 00:37:47,354
Leo Dion (host): Before we close
out let's talk about APIs, dub.

722
00:37:48,214 --> 00:37:52,284
Where do you think Core Data, Swift Data,
where are you at with that right now?

723
00:37:53,770 --> 00:37:56,530
Donny Wals (guest): So Maxine is all
Swift data and I'm not hating it.

724
00:37:57,110 --> 00:38:01,790
Mainly because… I wasn't expecting
to hate it at all because it's a

725
00:38:02,380 --> 00:38:04,320
pretty simple app database-wise.

726
00:38:05,000 --> 00:38:09,010
No multithreading, no
multiple axes, no iCloud sync.

727
00:38:09,730 --> 00:38:13,750
Just, you know, it's just on
a phone, local database, model

728
00:38:13,750 --> 00:38:14,930
changes every once in a while.

729
00:38:15,680 --> 00:38:16,830
Migrations work fine.

730
00:38:17,170 --> 00:38:20,530
A couple things that are a little
bit annoying around migrations,

731
00:38:20,530 --> 00:38:23,250
but once you know how they work
it's not that big of a deal.

732
00:38:24,000 --> 00:38:28,690
Mainly, like, when you want to
remove a property from a model and

733
00:38:28,690 --> 00:38:30,630
then move it to some other entity.

734
00:38:30,870 --> 00:38:31,630
Pretty vague, I know.

735
00:38:32,170 --> 00:38:35,060
So what I wanted to do at some point
I had an integer, like three integers

736
00:38:35,070 --> 00:38:39,240
somewhere on an object, and I wanted
to make those three integers parts

737
00:38:39,240 --> 00:38:43,230
of a new entity, and then the old
entity didn't have the three numbers

738
00:38:43,230 --> 00:38:45,080
anymore, just one field that pointed to

739
00:38:45,492 --> 00:38:47,792
Leo Dion (host): This is migration stuff?

740
00:38:48,312 --> 00:38:48,582
Okay.

741
00:38:48,692 --> 00:38:52,242
Donny Wals (guest): And Swift data cannot
do that in one pass, so you need two

742
00:38:52,242 --> 00:38:57,102
model versions, one to copy, and then
the other one to remove the old property.

743
00:38:57,392 --> 00:38:58,962
In Core Data, I could do that in one pass.

744
00:38:58,972 --> 00:39:01,792
So when I ran into that, it
was really annoying 'cause I

745
00:39:01,792 --> 00:39:02,542
was like, How do I do this?

746
00:39:02,562 --> 00:39:03,222
I cannot do this.

747
00:39:03,222 --> 00:39:05,662
Okay, fine, two model
versions it is." Turns out

748
00:39:05,810 --> 00:39:06,410
Leo Dion (host): Or they should…

749
00:39:06,482 --> 00:39:07,132
Donny Wals (guest): the way I had to do it

750
00:39:07,680 --> 00:39:10,660
Leo Dion (host): Yeah, you think they'd
have a tempor- like I, I don't know

751
00:39:10,660 --> 00:39:14,210
if you were a SQL person, but there's
always the idea of a temporary table.

752
00:39:14,210 --> 00:39:16,760
Like you'd think there'd be a way
to script something like that up

753
00:39:17,046 --> 00:39:17,166
Donny Wals (guest): Yep.

754
00:39:17,166 --> 00:39:18,626
Yeah, and Cordata does that, right?

755
00:39:18,626 --> 00:39:22,046
Cordata gives you old context and new
context, so you can query anything you

756
00:39:22,046 --> 00:39:24,686
had in your old database, and you can
query anything you have in your new

757
00:39:24,686 --> 00:39:26,356
one, and you can link stuff together.

758
00:39:26,776 --> 00:39:32,766
SwiftData gives you old context
and new context but not in the same

759
00:39:32,776 --> 00:39:34,396
function, so not in the same pass.

760
00:39:34,856 --> 00:39:39,686
And because it spins up a new container
for each you cannot go "Okay, so I

761
00:39:39,686 --> 00:39:46,006
want this object by object identifier,"
because in the new database it doesn't

762
00:39:46,056 --> 00:39:48,646
exist, 'cause it's changing that stuff.

763
00:39:48,716 --> 00:39:51,456
I don't know exactly how it
works, but you cannot get old

764
00:39:51,456 --> 00:39:52,846
objects into the new database,

765
00:39:53,360 --> 00:39:56,110
Leo Dion (host): Would you be like, "Yeah,
SwiftData all the way, all the time"?

766
00:39:56,110 --> 00:40:00,120
Or where would you think SwiftData just,
where are the rough edges right now?

767
00:40:01,154 --> 00:40:05,884
Donny Wals (guest): I think mainly
when you want to have sharing support

768
00:40:05,994 --> 00:40:08,014
from NSPersistentCloudKitContainer.

769
00:40:08,244 --> 00:40:09,804
That doesn't exist in SwiftData.

770
00:40:10,664 --> 00:40:14,294
I would say if you need advanced
compound predicates and everything,

771
00:40:14,294 --> 00:40:16,854
which I think iOS 27 will have.

772
00:40:17,654 --> 00:40:22,574
So that's quite nice, but at the
same time, it's iOS 27 plus, so quite

773
00:40:22,574 --> 00:40:26,084
older iOS versions won't have it, so
you're gonna have to probably figure

774
00:40:26,084 --> 00:40:28,874
out a way to use Core Data anyway.

775
00:40:29,164 --> 00:40:33,164
I would say in a heavily multi-threaded
environment as well, where you want

776
00:40:33,164 --> 00:40:37,614
to make use of scratch contexts make
sure that things run in the background.

777
00:40:38,744 --> 00:40:41,504
I found that you can do it with SwiftData.

778
00:40:42,334 --> 00:40:46,224
It's… And I haven't been bitten by
it yet, but I feel like SwiftData's

779
00:40:46,224 --> 00:40:53,194
model relies on trust a lot in the
sense that you can pass your models to

780
00:40:53,194 --> 00:40:58,034
any thread, and the Core Data thread
checker isn't going to fail on them.

781
00:40:58,910 --> 00:40:59,240
Leo Dion (host): Okay

782
00:40:59,314 --> 00:41:03,954
Donny Wals (guest): But I'm not exactly
sure that your models are fully threat

783
00:41:03,954 --> 00:41:10,114
safe and sendable, and it all gets
a little bit like, it should work.

784
00:41:10,224 --> 00:41:11,634
I've been told that it should work.

785
00:41:12,374 --> 00:41:16,044
It's just Core Data has given me a lot
of trust issues around these things.

786
00:41:16,804 --> 00:41:19,094
Like whenever they would say "With
Core Data, just trust us, it'll work."

787
00:41:19,104 --> 00:41:20,004
It's i'm gonna,

788
00:41:20,008 --> 00:41:22,978
Leo Dion (host): You're saying
core data you trust less or Swift

789
00:41:22,978 --> 00:41:23,248
data

790
00:41:23,390 --> 00:41:25,620
Donny Wals (guest): I would say, so
I don't trust either, but in Core

791
00:41:25,620 --> 00:41:27,780
Data I have a way to take control

792
00:41:28,436 --> 00:41:28,786
Leo Dion (host): Okay.

793
00:41:28,920 --> 00:41:29,820
Donny Wals (guest): that
I know what I'm doing.

794
00:41:30,280 --> 00:41:33,470
Swift Data, on the other hand they're
like, "Oh, no this should work fine. This

795
00:41:33,470 --> 00:41:35,510
should be managed in a model container."

796
00:41:36,050 --> 00:41:41,440
Core Data has this annoying problem if you
have a widget and an app, and they both

797
00:41:41,460 --> 00:41:46,710
operate on the same SQLite store, that you
can easily get crashes when both want to

798
00:41:46,710 --> 00:41:50,090
write or both want to read, 'cause there's
only supposed to be one connection active.

799
00:41:50,760 --> 00:41:52,930
Swift Data says you can do that now.

800
00:41:53,720 --> 00:41:54,110
Leo Dion (host): Okay.

801
00:41:54,958 --> 00:41:55,878
Donny Wals (guest): I don't trust that

802
00:41:56,410 --> 00:41:57,310
Leo Dion (host): Yeah, I agree

803
00:41:58,338 --> 00:41:59,468
Donny Wals (guest): because
I have trust issues.

804
00:41:59,518 --> 00:42:03,378
There-- I haven't had actual problems,
but I have trust issues, right?

805
00:42:03,408 --> 00:42:06,388
Core Data bit me too many times
with those kinds of things.

806
00:42:07,228 --> 00:42:11,918
And it's also in Swift Data, there's
bits and pieces scattered out there on,

807
00:42:11,918 --> 00:42:16,978
like, how it should work, but there's
no official guidance, especially on

808
00:42:16,978 --> 00:42:18,518
complex topics, where you're like I

809
00:42:18,662 --> 00:42:21,372
Leo Dion (host): Would you go
like a, with a SQLite type or

810
00:42:21,382 --> 00:42:25,192
SQLite adjacent library instead?

811
00:42:25,192 --> 00:42:26,512
Or what's your position now?

812
00:42:27,352 --> 00:42:31,152
So like in my case, I don't want to
keep going with SwiftData in my apps.

813
00:42:31,882 --> 00:42:35,252
I actually would want to migrate away
from it w- especially with Bushel.

814
00:42:36,062 --> 00:42:39,292
But maybe, like there's a couple
of apps which are, they're fairly

815
00:42:39,292 --> 00:42:43,422
simple where SwiftData would make
more sense, but I'm not like super

816
00:42:43,422 --> 00:42:45,532
happy with SwiftData and how it works.

817
00:42:45,542 --> 00:42:51,082
It's very SwiftUI tied and not
like database tied, I guess.

818
00:42:51,152 --> 00:42:52,052
I don't know how to put it,

819
00:42:52,122 --> 00:42:52,972
Donny Wals (guest): yeah I get that.

820
00:42:52,972 --> 00:42:58,862
It's definitely a UI abstraction
over SwiftData in some way,

821
00:42:58,902 --> 00:43:00,922
o- over SQLite in many ways.

822
00:43:01,652 --> 00:43:07,972
I… Especially for a magazine, I
don't hate it to the point where

823
00:43:07,972 --> 00:43:10,502
I would want to switch off of it.

824
00:43:11,312 --> 00:43:11,812
Do you know what I mean?

825
00:43:11,812 --> 00:43:12,652
It's fine.

826
00:43:12,702 --> 00:43:14,642
It's not causing me any problems.

827
00:43:15,102 --> 00:43:17,332
I don't have any
performance issues with it.

828
00:43:18,072 --> 00:43:21,412
Leo Dion (host): Benefits to using Core
Data with an app like Magazine either,

829
00:43:21,592 --> 00:43:23,142
Donny Wals (guest): There's
also no benefits to switching

830
00:43:23,152 --> 00:43:24,392
to something like GRDB.

831
00:43:25,082 --> 00:43:27,372
I did try GRDB in the beginning.

832
00:43:27,802 --> 00:43:29,812
Interestingly, 'cause everybody
told me like, "Oh, it's so much

833
00:43:29,812 --> 00:43:33,512
easier." Interestingly enough,
I found it so much harder

834
00:43:34,116 --> 00:43:34,406
Leo Dion (host): Okay.

835
00:43:34,432 --> 00:43:37,612
Donny Wals (guest): than SwiftData and
Core Data, maybe because I've been using

836
00:43:37,622 --> 00:43:41,662
both of those for such a long time that
using something else to me felt like,

837
00:43:41,662 --> 00:43:43,492
"Oh why do I have to relearn database?"

838
00:43:43,512 --> 00:43:44,642
I know how to do

839
00:43:44,808 --> 00:43:48,218
Leo Dion (host): my chief experience is
with Fluent, which is the server side

840
00:43:48,218 --> 00:43:51,378
Swift library, and I'm used to that.

841
00:43:51,628 --> 00:43:54,778
So there was some adjustment to
be made when I switched over to

842
00:43:54,808 --> 00:43:59,208
SwiftData, and I haven't done Core
Data in at least a decade, so yeah

843
00:43:59,418 --> 00:43:59,848
Donny Wals (guest): Oh, yeah.

844
00:44:00,638 --> 00:44:08,378
Yeah, I can imagine if you were to come
from a more, let's say ORM style thing to

845
00:44:08,378 --> 00:44:12,028
SwiftData, which is like its own… it's
not, I guess it's not technically an ORM.

846
00:44:12,048 --> 00:44:16,988
I think Core Data was pitched as like
a graph management tool or something

847
00:44:17,020 --> 00:44:17,350
Leo Dion (host): right.

848
00:44:17,360 --> 00:44:18,740
It's like a abstraction layer.

849
00:44:18,750 --> 00:44:19,490
Yeah, I get it.

850
00:44:19,884 --> 00:44:20,334
Donny Wals (guest): Yeah.

851
00:44:20,810 --> 00:44:21,000
Leo Dion (host): Yeah

852
00:44:21,524 --> 00:44:23,574
Donny Wals (guest): I can totally
see like how that would be

853
00:44:24,172 --> 00:44:24,652
Leo Dion (host): Annoying?

854
00:44:24,704 --> 00:44:27,014
Donny Wals (guest): To deal with when
you're used to a certain level of

855
00:44:27,014 --> 00:44:29,154
control and certain level of doing things

856
00:44:30,348 --> 00:44:33,048
Leo Dion (host): Before we close
out, I guess this is the second

857
00:44:33,048 --> 00:44:36,928
time I've said that maybe, but I
could, I, What's next for Donny?

858
00:44:36,978 --> 00:44:42,408
What kind of books should we expect,
if any, in the next couple of years?

859
00:44:42,438 --> 00:44:46,148
And has there… And additionally
I'm gonna ask, was there anything out

860
00:44:46,148 --> 00:44:49,658
of Dub that you were like, "I wanna
write a book about that," or something

861
00:44:49,658 --> 00:44:51,918
that really caught your attention?

862
00:44:52,918 --> 00:44:53,838
Donny Wals (guest): So I don't know.

863
00:44:53,898 --> 00:44:59,118
I started working on a Swift
data book, which I think I'm, I

864
00:44:59,118 --> 00:45:01,238
might not finish, I might finish.

865
00:45:01,268 --> 00:45:04,668
I have no idea right now
where I'm at with that.

866
00:45:06,578 --> 00:45:09,748
So whether I'm gonna do more books
I really don't know at this point.

867
00:45:09,778 --> 00:45:14,878
I think for me to do more books, the
concurrency book has to pick up again

868
00:45:15,428 --> 00:45:17,368
'cause that was in demand a lot.

869
00:45:18,038 --> 00:45:22,258
And then somewhere in the last quarter of
2025, that sort of just took a nosedive,

870
00:45:22,704 --> 00:45:23,154
Leo Dion (host): Wow.

871
00:45:23,204 --> 00:45:23,374
Okay

872
00:45:23,598 --> 00:45:27,768
Donny Wals (guest): which very clearly
says to me people are not interested in

873
00:45:27,778 --> 00:45:29,808
learning the details of how this works.

874
00:45:30,418 --> 00:45:32,818
They want their agents to know
the details, and there are skills

875
00:45:32,818 --> 00:45:34,138
out there that people can use.

876
00:45:34,838 --> 00:45:39,828
And I th- I do feel like eventually people
will come back from that because they

877
00:45:39,828 --> 00:45:41,538
have no idea what the agent is doing.

878
00:45:41,598 --> 00:45:43,248
Concurrency is really hard.

879
00:45:43,918 --> 00:45:47,308
Even with skills, it might still
make poor decisions because of,

880
00:45:48,328 --> 00:45:51,958
probably because the user doing a
poor job explaining what they want.

881
00:45:52,878 --> 00:45:54,958
So yeah, maybe we'll come back to that.

882
00:45:55,068 --> 00:45:55,858
So I have no idea.

883
00:45:55,988 --> 00:45:59,858
In terms of what's next, I'm still very
heavily thinking what do I do next?

884
00:46:00,548 --> 00:46:04,678
I am dabbling in indie apps shipping
my own stuff, which I chose the

885
00:46:04,678 --> 00:46:08,628
hardest niche to get into, I
think, which is health and fitness.

886
00:46:09,158 --> 00:46:09,948
But it's fun.

887
00:46:10,008 --> 00:46:11,138
I'm liking it a lot.

888
00:46:11,388 --> 00:46:12,658
So yeah, that's good.

889
00:46:13,718 --> 00:46:15,998
Maybe other apps, maybe other
ideas will come at some point.

890
00:46:15,998 --> 00:46:17,148
I have no idea.

891
00:46:18,018 --> 00:46:20,698
YouTube, I do want to pick that up again.

892
00:46:20,708 --> 00:46:23,458
I've been putting that on hold as
well while I figure out what am

893
00:46:23,458 --> 00:46:25,658
I gonna do exactly content-wise.

894
00:46:26,156 --> 00:46:26,486
Leo Dion (host): Mm-hmm

895
00:46:26,538 --> 00:46:29,918
Donny Wals (guest): I'm leaning
more towards maybe a live stream

896
00:46:29,918 --> 00:46:37,778
format where just co-working or more
workflow, higher level stuff, like

897
00:46:37,778 --> 00:46:42,778
not tutorials, not here's how to do
X or not here's how I like to do this

898
00:46:42,888 --> 00:46:45,308
this UI part or how I architect this.

899
00:46:45,858 --> 00:46:48,558
But a lot more high level,
like how do I work with agents?

900
00:46:48,648 --> 00:46:50,388
Like how do I manage context windows?

901
00:46:50,418 --> 00:46:53,138
How do I describe architecture?

902
00:46:53,148 --> 00:46:54,538
How do I review code?

903
00:46:54,918 --> 00:46:57,468
How do I recognize when my
agent's going after rails?

904
00:46:58,058 --> 00:46:59,518
Those kinds of things.

905
00:46:59,538 --> 00:47:00,158
But I have no

906
00:47:00,262 --> 00:47:03,622
Leo Dion (host): like off the rails,
like it's going crazy, not Ruby, right?

907
00:47:03,732 --> 00:47:03,892
Donny Wals (guest): Yeah.

908
00:47:03,892 --> 00:47:08,892
Like how do I recognize that I should
probably stop the agent mid-task?

909
00:47:09,642 --> 00:47:13,922
'Cause like you can just leave it
running and sometimes… I do still

910
00:47:13,922 --> 00:47:18,032
think there's a ton of value in deeply
understanding what the agent is doing

911
00:47:18,042 --> 00:47:20,362
in terms of how should the code look and

912
00:47:20,408 --> 00:47:23,718
Leo Dion (host): There was a way in
Claude Code where you could have it

913
00:47:23,718 --> 00:47:26,658
tell you what it's thinking while it
does something, and I don't know if they

914
00:47:26,658 --> 00:47:28,828
got rid of it or it's no longer there.

915
00:47:28,828 --> 00:47:31,498
I need to re-enable it
because it's really helpful

916
00:47:31,558 --> 00:47:33,938
Donny Wals (guest): I've,
used that many times.

917
00:47:33,978 --> 00:47:35,558
I've had that when You have your plan.

918
00:47:35,658 --> 00:47:36,738
Plan mode is great.

919
00:47:37,158 --> 00:47:38,108
Everything looks fine.

920
00:47:38,458 --> 00:47:39,938
The files, it lists it.

921
00:47:40,028 --> 00:47:40,698
It looks good.

922
00:47:40,858 --> 00:47:43,518
Then it starts doing the work
and it's "Oh, we need to remove

923
00:47:43,528 --> 00:47:45,978
the old model version because
there's a new model version."

924
00:47:45,978 --> 00:47:47,518
No, don't remove anything.

925
00:47:47,528 --> 00:47:48,318
Don't do that.

926
00:47:48,368 --> 00:47:49,678
Do not remove anything.

927
00:47:49,688 --> 00:47:51,268
You're making new model versions.

928
00:47:51,268 --> 00:47:53,398
Model versions are
additive, not destructive.

929
00:47:54,108 --> 00:47:58,708
And if I had let that run, it could've
spent like 30 minutes to an hour

930
00:47:59,118 --> 00:48:02,158
doing work, and then I come back,
it's why does nothing work anymore?"

931
00:48:02,784 --> 00:48:03,624
Leo Dion (host): Right, right.

932
00:48:03,784 --> 00:48:05,504
Yeah, thinking mode is what it's called.

933
00:48:06,004 --> 00:48:07,324
So yeah.

934
00:48:07,844 --> 00:48:13,054
Well, Donnie let's do this again
before the AI apocalypse or AI bubble.

935
00:48:13,524 --> 00:48:14,664
One or the other, we'll see.

936
00:48:14,714 --> 00:48:15,464
We'll flip a coin and we'll

937
00:48:15,464 --> 00:48:16,094
see which way it

938
00:48:16,220 --> 00:48:16,870
Donny Wals (guest): something will happen

939
00:48:18,474 --> 00:48:20,024
Leo Dion (host): where can
people find you online?

940
00:48:20,710 --> 00:48:22,490
Donny Wals (guest): On X, Donny Walls.

941
00:48:22,590 --> 00:48:25,220
On, I think Mastodon also Donny Walls.

942
00:48:25,370 --> 00:48:28,240
On all the social networks,
just find Donny Walls.

943
00:48:28,380 --> 00:48:31,440
And if you cannot find me by Donny
Walls, find me by Donny Walls Dev,

944
00:48:31,480 --> 00:48:36,150
which I think is what I had to use on
Instagram because somebody stole Donny

945
00:48:36,150 --> 00:48:39,040
Walls, and they're not even a Donny Walls

946
00:48:39,540 --> 00:48:40,960
Leo Dion (host): what
does that Donny Walls do?

947
00:48:41,600 --> 00:48:42,040
Do you

948
00:48:42,164 --> 00:48:43,174
Donny Wals (guest): steal my stuff.

949
00:48:43,850 --> 00:48:44,340
Leo Dion (host): Oh, man.

950
00:48:44,834 --> 00:48:48,384
Donny Wals (guest): Like
literally it's I tried many times.

951
00:48:48,774 --> 00:48:52,984
No so what they did is they posted
like some weird picture, then three

952
00:48:52,984 --> 00:48:55,834
pictures that they stole on my page, and
then one other picture, and then they

953
00:48:55,844 --> 00:48:57,574
haven't posted for six or seven years.

954
00:48:58,234 --> 00:49:01,244
And every once in a while write
to Instagram yeah, I write them

955
00:49:01,254 --> 00:49:03,804
like, "Hey, that's my name.

956
00:49:04,304 --> 00:49:08,454
That's my photos." And they ended up
taking down my photos, but they're

957
00:49:08,454 --> 00:49:10,854
like, "Yeah, well nothing we can
do about them using your name."

958
00:49:11,450 --> 00:49:11,500
Leo Dion (host): What?

959
00:49:11,504 --> 00:49:14,214
Donny Wals (guest): was like, "Okay."
They're not even using the account.

960
00:49:15,014 --> 00:49:16,024
Like it, it sucks.

961
00:49:16,264 --> 00:49:16,634
Yeah.

962
00:49:17,310 --> 00:49:19,680
Leo Dion (host): Thank you
again for coming on the show.

963
00:49:19,780 --> 00:49:20,730
It was fantastic.

964
00:49:20,864 --> 00:49:21,354
Donny Wals (guest): for having me

965
00:49:22,190 --> 00:49:26,730
Leo Dion (host): people can find
me online @leogdion, @leogdion.c.im

966
00:49:26,730 --> 00:49:31,060
on Mastodon YouTube, we're at
BrightDigit is the name of the channel.

967
00:49:31,220 --> 00:49:34,460
If you're watching this on YouTube,
and subscribe, and also and

968
00:49:34,460 --> 00:49:36,060
subscribe to Donnie's channel too.

969
00:49:36,560 --> 00:49:40,840
If you're on a podcast player,
please go ahead and post a review.

970
00:49:40,880 --> 00:49:42,090
I'd really appreciate it.

971
00:49:42,910 --> 00:49:43,840
Oh, one more thing.

972
00:49:43,880 --> 00:49:45,420
I have a newsletter again.

973
00:49:45,490 --> 00:49:46,080
Yay.

974
00:49:46,140 --> 00:49:47,890
I'm gonna post a link to the newsletter.

975
00:49:47,940 --> 00:49:52,560
I finally m- moved from MailChimp
to Buttondown, and it's a lot

976
00:49:52,560 --> 00:49:54,160
nicer definitely check that out.

977
00:49:54,930 --> 00:49:56,890
And check out the Patreon.

978
00:49:56,890 --> 00:50:00,790
Thank you to Patreon supporters like
Steve Lipton for helping support the show.

979
00:50:01,610 --> 00:50:02,440
Oh, right.

980
00:50:02,450 --> 00:50:05,850
So I'm gonna be installing Windows
and learning about Windows.

981
00:50:05,890 --> 00:50:08,230
I haven't touched
Windows in over 12 years.

982
00:50:08,840 --> 00:50:13,710
So if you have any questions for
Selim, the I don't know, founder,

983
00:50:14,310 --> 00:50:18,640
principal motivator of Swift for
Windows drop me a line and let me

984
00:50:18,640 --> 00:50:21,800
know what you want me to ask him,
'cause he'll be in the next episode.

985
00:50:21,800 --> 00:50:23,030
We'll be talking about that story.

986
00:50:23,610 --> 00:50:27,220
Thank you again, and I look
forward to talking to you again.

987
00:50:27,260 --> 00:50:27,820
Bye, everybody.

988
00:50:28,822 --> 00:50:29,162
Donny Wals (guest): See ya