Episode Transcript
Transcripts are displayed as originally observed. Some content, including advertisements may have changed.
Use Ctrl + F to search
0:00
All right, we got to
0:02
talk about programming for a
0:04
second. So I'm working on this
0:06
charting library and it's
0:09
like, it's following the exact
0:11
same path as the date
0:13
picker. It's this pattern, you know,
0:15
where you just start a
0:17
thing, you just start like
0:19
running into the thicket of
0:22
a tough problem and you're
0:24
just like baton away like. you
0:26
know, bushes and thorns and you're
0:28
just running, you trip on a
0:30
log, that's the discovery phase. You're
0:33
making a mess. Claude's right in
0:35
half your code. It's just, you
0:37
know, you're just discovering, that's what
0:39
you're doing. You're discovering
0:41
the shapes of the problem domain, I
0:43
guess, but just the shapes of the
0:45
thing you're trying to build. You're
0:48
going, oh, that's a shape there,
0:50
that's like an axis or something,
0:52
like that's a concept, you're discovering
0:55
the concepts. Which at first
0:57
it starts out as broad
0:59
strokes like okay, there's an
1:01
x-axis and a y-axis and
1:03
then there's data along those
1:05
axes You know, okay, that's
1:07
simple enough and ticks like follow
1:09
the axes axis and they they
1:12
kind of happen at the points
1:14
that the data happens and you
1:16
have an x-y coordinate pixel system
1:18
and then you have you know,
1:20
value domains that map to those
1:23
pixels and like that's kind of
1:25
the initial concepts and you go,
1:27
all right, and then you try
1:29
to represent them in your code
1:31
as you go because, you know, it just slows
1:33
you way down if you just never take a
1:35
minute to like shore stuff up. But then
1:38
you just keep moving and then you find
1:40
like the next, the next place that your
1:42
code breaks down, which is usually, for
1:44
me, it comes in the form of
1:46
like, well, not only conditionals everywhere, but
1:49
then I start to realize that. Like,
1:51
you start to see the things you
1:53
don't understand or you start to see
1:56
the questions you have of like, oh,
1:58
wait a minute. So grid lines. Do
2:00
they align with ticks? Like ticks don't
2:02
always align with your data, especially on
2:04
the y-axis. Yeah, both axes, especially on
2:07
the y-axis. ticks don't align with your
2:09
data. So do you align grid lines
2:11
with, like that was one quick thing
2:14
I first ran into. It's like, my
2:16
horizontal grid lines were aligned with, well,
2:18
I guess? Yeah. I don't know. I
2:20
think the horizontal grid lines I initially...
2:23
Because gridlines just look evenly spaced. So
2:25
I initially had them just evenly spaced.
2:27
And then when I realized you have
2:30
to like calculate what value show up
2:32
on the y-axis for ticks, because the
2:34
x-axis is kind of easy. You can
2:37
just put a tick initially. You can
2:39
just put a tick at every data
2:41
point, but the y-axis is not like
2:43
that. It's like a linear scale, you
2:46
know? So you calculate those ticks, but
2:48
then, oh, they don't match up with
2:50
the horizontal gridline. So those gridlines need
2:53
to be bound to my y-axis ticks.
2:55
So that means I need to calculate
2:57
my ticks up front and make sure
3:00
that the code is all structured such
3:02
that it can all relate to each
3:04
other in this way. So that was
3:06
like one area where it's like, oh,
3:09
the system's breaking down, my mental model's
3:11
breaking down. There's relationships here that I
3:13
didn't see up front. And now I'm
3:16
starting to see. Like, ah, horizontal grid
3:18
lines map to ticks. Now, vertical grid
3:20
lines, do those map to data points,
3:23
or do they map to X-axis ticks?
3:25
Because X-axis ticks don't always map to
3:27
data points. Like in a time series,
3:29
there might be like increments of single
3:32
months, but there might be like many
3:34
data points within those months. Where do
3:36
your vertical grids, who do your vertical
3:39
grids align with? And the answer is
3:41
different. face was like, oh, grid lines,
3:43
go with ticks. And ticks, like, well,
3:45
whatever, there's, and then there's some chicken
3:48
and egg things that happened. I found
3:50
two chicken and eggs with charting. Like,
3:52
you need to draw the whole chart
3:55
first to know the size of everything,
3:57
to know if you need to like.
3:59
scale it down. And then once you
4:02
scale it down, you have to
4:04
redraw the whole chart. So there's
4:06
a lot of like relationships between
4:08
data and positions. But then you like
4:10
need to figure it all out first
4:12
and then redraw it to adjust spacing
4:14
for everything. So that's like a chicken
4:16
and egg. That's a solution. You know,
4:19
with chicken and egg problems, there's like,
4:21
I guess the best solution for a
4:23
chicken and egg. It's like, like, let the
4:25
chicken. And let the egg, like, like,
4:27
like, like, exist. Then let it hatch
4:29
into a chicken and then go back
4:32
and put it back in the egg.
4:34
So stupid. I don't think that worked.
4:36
So that was the first chicken and
4:38
egg problem. The second one I
4:40
just encountered is when you calculate the
4:43
domain of your data set, you know,
4:45
so if you're mapping like, you know,
4:47
you have a big array of objects
4:50
and each object has like the month
4:52
in it, the sales numbers for that
4:54
month, and the refund amount for that
4:57
month. So you have like... your x-axis,
4:59
your, remember the constant, these are
5:01
things that you haven't heard in
5:03
a while, domain, range, and independent
5:05
and dependent variables. You remember
5:08
those from math class? So
5:10
the dependent variable is the
5:12
y-axis, the thing that changes, the
5:15
independent variable, is the x-axis, the
5:17
thing that is constant, you know,
5:19
the thing that your data set
5:21
is related to, is your independent variable,
5:23
I believe. So... In this case, like
5:25
if you have this object of month,
5:28
sales, and refunds, month is your independent
5:30
variable. It's unchanging. It's the thing with
5:32
which you are comparing the other numbers.
5:34
And those other numbers are your series.
5:37
It's sort of like if you look
5:39
at this picture this Jason object, where
5:41
you have these objects, one on top
5:44
of the other, and there's three, basically
5:46
it's like a table with three columns.
5:48
The leftmost column is your independent variable.
5:50
The other columns, those slices, those
5:53
are series. And the plural of
5:55
series is series. It's a, it's
5:57
called a zero plural. These are
5:59
all the... random things you encounter
6:02
as you start working on
6:04
a thing you know like
6:06
deer series we already said
6:08
and it's access for singular
6:10
it's axes for plural which
6:12
is spelled like multiple hatchets
6:14
axes but it's it's funny
6:16
axes is spelled like ax
6:18
there's axis and then if
6:20
you have if you own
6:22
multiple things like tree cutting
6:24
implements. You have axes, but
6:26
if you're looking at multiple,
6:28
like reference lines on a
6:30
chart, they're axes, but they're
6:32
spelled the same as the
6:34
tree cutting implements. So that's
6:36
kind of fun. You know
6:38
what? The other one I
6:40
never get right is dice.
6:42
Dice. Plural of... Dice? No,
6:44
it's singular of dice. So
6:46
the plural of dice is
6:48
dice. Dice is an irregular
6:50
plural noun, so it doesn't
6:52
follow the rule of adding
6:54
right to the single world.
6:56
Dice is the plural of
6:58
the singular word die. Dice
7:00
can be used both as
7:02
a singular and plural. This
7:04
is clearing things up for
7:06
me. Okay, so it's one
7:08
die, but it can also
7:10
be one dice. You know?
7:12
But it's multiple dice, but
7:14
it can be multiple dice.
7:16
It's dice. Makes sense. Anyway,
7:18
where were we? These relationships,
7:20
the chickens and the eggs.
7:22
So I realized that it's
7:24
like when you calculate the
7:26
domain all the available, the
7:28
range of available values in
7:30
your chart, and then you
7:32
calculate the range, which is
7:34
the pixel values that those
7:36
are going to map to,
7:38
and then you calculate the
7:40
scale functions that convert arbitrary
7:42
values based on the domain
7:44
within that domain, within the
7:46
mins and maxes, into, you
7:48
know. relative pixel values for
7:50
the screen. But what I
7:52
realized is like when you
7:54
calculate ticks on the y-axis,
7:56
you might buffer like the
7:58
top tick because You might like
8:00
you could make it so that the
8:02
ticks happen in equal increments like 5
8:04
10 50 and then the top tick
8:06
is the the top most highest Y
8:09
value you have But like that kind
8:11
of looks a little weird. So you
8:13
often just overshoot You know, it's like
8:15
5 10 15 20 even if the
8:17
highest value in your in your line is
8:19
like 18, you know So now the
8:21
available domain on your chart is zero
8:23
through 20 not zero through 18. So
8:25
you have to calculate the initial domain
8:28
based on your data set Then you
8:30
have to draw all your ticks and
8:32
lay them out and decide what steps
8:34
they're going to be in. Then you
8:36
have to recalculate the domain based on
8:38
the new available, based on the
8:41
original values combined with the
8:43
tick values. Because sometimes ticks
8:45
might even be within the bounds of
8:47
your data set. So you kind of
8:49
have to do this like, well, whatever.
8:51
Anyway, that's a chicken and egg problem.
8:53
But you don't know. Like it's just...
8:56
It's just your code breaking down
8:58
and then you have to go
9:00
investigate why. Is it because you
9:02
don't understand something? Is it because
9:04
you thought there was a relationship
9:06
that there wasn't? There's all sorts
9:08
of those because like you have
9:10
an x-axis and a y-axis and
9:12
they're the same in so many ways,
9:15
but they're different in other ways.
9:17
Like for example, the x-axis is
9:19
a dependent variable. It will only
9:21
map to a single... a set of
9:24
values where the y-axis is
9:26
a it's an aggregate scale
9:28
it represents the scale of many
9:30
different series so anyway that changes
9:32
a lot of math so I
9:34
had rewrote the whole thing because
9:36
you know that's how it goes I
9:39
mean I've kind of rewrote them
9:41
all times but this was the
9:43
big rewrite and what was the
9:45
big revelation here the big revelation
9:48
was the same one it always
9:50
is separate the data from the
9:52
presentation of the data. Sit down,
9:54
this is me with a pen and
9:57
paper, sitting down, and figuring
9:59
out all of the properties, all of
10:01
the, all of the data. If
10:04
I made a giant god chart
10:06
object, what would the properties be?
10:08
With, height, axes, and then within
10:11
axes, it'd be X and Y,
10:13
and within X and Y, it
10:15
would be the field name, it
10:18
would be the scale, the domain,
10:20
the range, the scale, line paths,
10:22
like generators, like. all sorts of
10:24
stuff like that. Then there's series
10:26
inside the chart, which is an
10:29
array of all of the data
10:31
series that are going to be
10:33
mapped, you know, on the y-axis
10:35
and extra helper functions within those
10:38
series. Anyway, so all the data,
10:40
purely data, this is something that
10:42
I think charting gets wrong
10:44
almost universally is conflating the
10:47
data with the presentation. which
10:49
is like an obvious thing
10:51
to separate, but charting is
10:53
the worst offender when you're
10:55
defining a series, which is a line,
10:57
on a chart, or a bar, set of
10:59
bars, you might specify a color for the
11:02
series. But what if you want
11:04
different colors for the series, the
11:06
points on the series? And now
11:08
you, that's another config, and you
11:10
know, whatever. It's like colors live...
11:13
right next to line thicknesses or
11:15
stroke widths and they live right
11:17
next to like data keys and
11:19
hard numbers and that's wrong. So
11:21
I'm completely separating out the entire
11:23
data portion such that I basically
11:26
have an object that could drive
11:28
out like you could use this
11:30
if you were really brave you
11:32
could use this to drive out a
11:34
chart in alpine I think. Like it
11:36
would be fun to turn this into
11:38
an alpine plug in and just see
11:40
if like... I think alpine works
11:42
inside of SVCs. SVCs are
11:44
weird. They're in a different
11:47
name space. You ever like
11:49
seeing like N.S. in in
11:51
HDML stuff like when you're,
11:53
I don't know, where have I encountered
11:56
at us? I've definitely
11:58
encountered it. But SVG elements
12:00
are different than HDML elements. They're within
12:03
a different document name space. And there's
12:05
like little things that are just odd
12:07
or different, like a template tag inside
12:10
of an SVG doesn't work the same.
12:12
It won't really have any content. It's
12:14
not a normal, it's not like recognized
12:16
as an element. So that's like a
12:19
hurdle I had overcome, but anyhow. So
12:21
it makes things like dom crawling a
12:23
little bit weird. It can mostly work,
12:26
but there's weird stuff like in SVG,
12:28
transform and opacity and everything. Those are
12:30
attributes as well as CSS properties. Not
12:33
just CSS properties like in normal
12:35
HDML. So weird stuff. Anyway, I
12:37
think Alpine works inside of SVG.
12:39
I'm pretty sure. That'd be pretty
12:41
fun. This would be fun. Ooh, I should
12:43
do this. This is rivers. Yeah, we can do
12:45
it. Dad, we could do it. So yeah. Yeah. Yeah.
12:47
Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah.
12:50
Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. Yeah. That's something
12:52
I should do. Okay, so the thought
12:54
again just to reiterate that It's like
12:56
this is how it goes You gotta
12:58
just you gotta you gotta enter the
13:00
discovery phase and make big heaping piles
13:03
and messes Then to know what you
13:05
don't know to establish the concepts to
13:07
establish your constraints and your scope then
13:09
Then once you've already like
13:11
understood these things separate out the
13:13
data in the presentation and that
13:16
is your golden ticket Because you
13:18
can't do that up front because
13:20
you don't know the data and
13:22
you don't know the presentation So
13:24
it's I think it's better up
13:26
front to just make a giant mess
13:28
and then sit down with a pen
13:31
and pad and a cup of coffee
13:33
or tea and figure out You know
13:35
how you're going to represent it all
13:37
and have a good long chat with
13:39
chat GBT which in this instance was
13:41
way better than clod I'm getting so
13:43
sick a cursor cursor as dumb as
13:45
rocks that it's doing for me is
13:47
like recognizing when I make a change
13:50
on one line and I need to
13:52
make it on like 50 lines but
13:54
other than that it's constantly generating shit
13:56
code like constantly it is not helpful
13:58
to me in this code base anymore
14:00
at all, which is a huge
14:02
bummer. And I went back to
14:05
chat TBT for fun to just
14:07
see what chats up to and
14:09
have a conversation with chat about
14:12
some charting concepts while I was
14:14
like mapping out the chart object.
14:16
And it was like a breath
14:18
of fresh air. It wasn't shoving
14:21
react on my throat every two.
14:23
It was like way more
14:25
capable than Claude. It's so weird.
14:27
I don't follow the models. But
14:30
maybe chat just like has something
14:32
better now that's awesome. I don't
14:34
know. Try it out. It's nice.
14:37
It's faster too. The interface is
14:39
better. Feels cleaner. Even though clots
14:41
like constantly generating like code and
14:43
trying to run it for you.
14:45
And it's just not that useful.
14:48
Like I just don't, that's not how
14:50
I work with AI, I don't want
14:52
to like iterate on a thing that
14:55
we're testing in the browser because I'm
14:57
always looking for pieces, you know, I'm
14:59
never looking for like, Alexa make
15:02
me an app, you know, because it's
15:04
going to be a heaping dumpster fire
15:06
mess and and make the like, you
15:08
know, the, whatever, the size, token,
15:10
document, whatever thing that you send
15:13
back and forth, you're going to
15:15
like bust through your AI limit.
15:17
We're really rambling today, huh? Yeah,
15:19
so that's, you know, you work
15:22
with chat TVT and you bring,
15:24
you bring, yeah, you figure out
15:26
the domain and then you separate
15:28
the data in the presentation and
15:31
you do that. And that's great.
15:33
And that's the pattern to like
15:35
solving a tough programming problem and
15:37
it's nice. Okay, so another thing
15:39
that I wanted to mention at
15:42
some point, which we're, what's our time
15:44
here? Oh yeah, we're already 15, let's
15:46
go 20. think react well
15:48
we'll see because if I
15:50
turn this into an alpine
15:52
plug-in and it's like really
15:54
awesome and I love it that'll
15:56
be fun but I think that
15:58
frameworks I think the
16:01
perfect place to
16:03
be is your UI
16:06
widgets, basically, is the
16:08
wrong level
16:10
of abstraction
16:12
for componentry,
16:14
for discrete UI
16:16
widgets, basically.
16:19
I think the perfect
16:21
place to be is your
16:24
UI widgetry is
16:26
self-contained.
16:28
And it's self-contained. That's
16:30
something that I dislike,
16:32
and I don't work
16:34
and react every day,
16:36
granted. But something I dislike,
16:39
I mean, it applies to
16:41
alpine as well. Something I
16:43
dislike about using these frameworks
16:45
where they break down for
16:47
me is when you zoom way in, you
16:50
know, when you're doing surgery
16:52
on very nitty gritty things.
16:54
That's where they break down.
16:57
And I've sourced of so
16:59
many react widget libraries. It's
17:02
insane. And inevitably, when I
17:04
read react app code, it's not
17:07
so bad. Same thing with view
17:09
code and whatever. But when you
17:11
look, when you like, when you
17:13
see it being used for
17:16
very surgical things, like a
17:18
charting library, or even
17:20
a drop down menu, like a
17:22
real, you know, one with the
17:24
like, drag over stuff. When you see
17:26
that, you see how it all breaks down. It's
17:29
not fun anymore. It's gnarly. And
17:31
here's what's wrong with it. What's
17:33
wrong with it is, well, A,
17:35
often, like, a lot of the
17:37
optimizations of these libraries kind of
17:39
break down at that level of
17:41
granularity and you end up trying,
17:43
end up wrestling with them more
17:45
than anything and having to really
17:47
lean on things like memoization or
17:49
whatever, because RAC, I mean, specifically,
17:51
is kind of built for... course
17:53
grain updates where it's like gonna
17:56
it's gonna like re-render everything you
17:58
know and then find the diffs
18:00
and patch them, which isn't
18:03
necessarily what you want, because
18:05
you might, well, whatever, you might
18:07
need to, you might have a
18:10
thousand ticks on a line, or
18:12
you might have like a thousand
18:14
points on a grid, and you
18:16
might have like a thousand points
18:18
on a grid, and we might
18:21
have to update that a
18:23
hundred times in five milliseconds
18:25
or something that you pay
18:27
the cost for. In simple
18:29
way, like if you have a ton
18:32
of work to be done, a scheduler
18:34
is good and is going to help
18:36
you, but if you are not doing
18:38
a ton of work, you pay a
18:40
cost by using a scheduler in general.
18:42
And there's so many things like that,
18:44
where you just have all this overhead,
18:46
not to mention the cognitive overhead and
18:48
the conceptual overhead and the siloing of
18:51
all these useful widgets that are now
18:53
silo to react for no good reason.
18:55
And you like, yeah, it's frustrating to
18:57
me. is the place to be for
18:59
discrete UI widgetry because
19:01
it's not rocket science like it's
19:04
dom manipulation. You already know it.
19:06
It's like you create an element,
19:08
you append it on a page,
19:10
you set some attributes, you move
19:13
it around, that's kind of it.
19:15
It's like... you can delete the element,
19:17
you can change its text content, you
19:19
can crawl its children, whatever, and you
19:21
can just kind of get done what
19:23
you need to get done. And you
19:26
have full control over when an element
19:28
is rendered versus when it is updated,
19:30
how often it is updated, you can
19:32
create your own little observable, you know,
19:35
engine that can fully control those
19:37
updates, you're not relying on, you
19:39
know, um... on like the system to detect
19:41
when your data changes to re-render everything,
19:43
you would get more control over that.
19:46
You can re-render the only things that
19:48
need to change when some other thing
19:50
changes. And the massive benefit of this,
19:52
aside from all those other reasons, is
19:55
that work can be shared across ecosystems.
19:57
How amazing would it be if React
19:59
Aria was... custom web elements like
20:01
shoelaces or if it was just
20:04
something that that was embraced by
20:06
all ecosystems and was written in
20:08
vanilla JavaScript and for vanilla non-frame
20:11
for non-frame work front-end I guess
20:13
then we could all use it
20:16
and wouldn't that be a wonderful
20:18
life there is an alternate universe
20:20
where I make this my mission and I
20:22
take all of the work that I'm
20:24
doing and make it like a crusade to
20:27
bring you know, to be the
20:29
savior of the non-react world.
20:31
But that's a pretty thankless
20:34
job. And it's definitely not
20:36
an income generating job. And
20:38
it's really what you're doing
20:41
is just fueling other people
20:43
to make money off you. But
20:45
that's my new cynical open
20:47
source take. Anyway, so yeah, so
20:50
those are some thoughts. But yeah,
20:52
I think discrete UI
20:54
widgetry is best done by few
20:56
people. by the way, I think there
20:58
should be, you know, I don't think, I
21:01
don't think everybody should be doing
21:03
this. I think few people who
21:05
want to really roll up their
21:07
sleeves and live this life should
21:10
do this for everyone else. And
21:12
then everybody, which is what I'm
21:14
doing, and by for everyone else,
21:16
I mean purchasers of flux. And
21:18
then everybody else for my
21:21
circumstance. And everybody
21:23
else can stay at the application
21:25
layer. They can stay at
21:28
mapping their database. They
21:30
can stay at configuring
21:32
this, this UI
21:35
component widgetry to
21:38
get data in and
21:40
to show the data out.
21:42
That's the layer that
21:44
web developer is
21:46
going to sit in. And
21:48
yeah, so that's the way
21:51
it should be. I don't
21:53
know. Have we said anything.
Podchaser is the ultimate destination for podcast data, search, and discovery. Learn More