WEBVTT Supercharging Python Tooling with Charlie Marsh

STYLE
::cue(c.speaker) {
color: cyan;
}

00:00:21.180 --> 00:00:22.490
<c.speaker>Tim:</c> Hi everyone, welcome!

00:00:22.870 --> 00:00:32.619
This is Charlie Marsh from Astral and,
uh, you, Charlie, have been building
something I find slightly incredible.

00:00:32.869 --> 00:00:37.450
So this is my perception
of, of, of what you've done.

00:00:37.450 --> 00:00:40.879
You thought, oh look, I've got
this linter ruff that's suddenly

00:00:40.879 --> 00:00:45.750o
going to make the life of Python
developers 50 to 100 times better?

00:00:46.330 --> 00:00:49.770
And then, Oh, it's like, by the way,
we're just going to bring out uv, 

00:00:49.770 --> 00:00:53.780
hire some of the best Rust programmers in the
world to create this amazing company.

00:00:54.259 --> 00:00:59.759
We have adopted this Rye
thing as well, which is
kind of like adjacent to that.

00:01:00.429 --> 00:01:07.740
And now you have made the
lives of millions of Python
programmers dramatically better.

00:01:07.740 --> 00:01:09.259
Like what a gift to the world.

00:01:11.585 --> 00:01:12.195
<c.speaker>Charlie:</c> Thank you.

00:01:12.215 --> 00:01:15.294
Um, no, I, uh, I, I
really appreciate that.

00:01:15.294 --> 00:01:21.615
I mean, I, I don't know if I would,
um, say such nice things about myself,
but, um, I appreciate you saying them.

00:01:21.975 --> 00:01:30.784
Um, I think, uh, I love working
on tools, um, because it's such an
amazing, like, platform for impact.

00:01:31.144 --> 00:01:34.125
And, um, you know, originally when
we were, when I started working

00:01:34.125 --> 00:01:37.620
on ruff, I, It was really fun, but
like no one was really using it.

00:01:38.890 --> 00:01:42.500
Um, and I got, it was very
gratifying, you know, in some
ways and maybe not in others.

00:01:42.500 --> 00:01:47.609
And now, um, you know, we're kind
of at the point now where, you know,
if we ship a really big improvement

00:01:47.620 --> 00:01:54.900
to ruff, um, It immediately goes out
and impacts, you know, a very large
portion of the entire Python ecosystem.

00:01:54.940 --> 00:01:59.720
Um, and new capabilities and
new, new powers start showing
up in your editor, right?

00:01:59.720 --> 00:02:01.709
And like new workflows become possible.

00:02:02.000 --> 00:02:09.760
So, um, I love working on tooling, um,
and I think the idea, That, um, we get to
kind of keep in a compounding way, make

00:02:09.760 --> 00:02:12.750
Python better and better and better is
really one of the big drivers of, of like

00:02:12.750 --> 00:02:16.280
why I am working on this stuff and why all
the people on the team have joined too.

00:02:16.520 --> 00:02:21.570
<c.speaker>Tim:</c> Python seems to be going
through, I'd say, somewhat of
a renaissance or renaissance.

00:02:21.960 --> 00:02:25.080
Uh, the, uh, with like Python 3.

00:02:25.790 --> 00:02:32.709
Uh, where Python's 13 has
just been, uh, has landed with
sub-interpreters and no GIL.

00:02:32.950 --> 00:02:40.600
And it just feels as though there is,
has been this, a reaction to say static

00:02:40.649 --> 00:02:45.600
typing with mypy, for example, originally,
and that being pulled into the language.

00:02:45.970 --> 00:02:52.595
And now with tooling such as your
own, you have, uh, Essentially, this

00:02:52.595 --> 00:02:55.695
compounding effect, that's a really
interesting way to express that.

00:02:55.695 --> 00:03:04.675
Why, why did you think that you
could do something different
than what had already happened?

00:03:04.704 --> 00:03:09.734
Because when Ruff was being
created, there was already Pylint.

00:03:09.765 --> 00:03:14.075
There was already probably, I think
Black was also, was quite prominent.

00:03:15.095 --> 00:03:15.435
<c.speaker>Charlie:</c> Yep.

00:03:16.335 --> 00:03:16.755
Yeah.

00:03:16.815 --> 00:03:17.975
<c.speaker>Tim:</c> And you thought, you
know what, we could do better.

00:03:17.994 --> 00:03:18.024
Yep.

00:03:20.234 --> 00:03:26.969
<c.speaker>Charlie:</c> Ya, I think, um, you know,
one of the big drivers for me,
um, in, in working on this kind of

00:03:26.969 --> 00:03:34.039
tooling was, um, I was seeing a lot
of what was happening in the, the web
ecosystem and the JavaScript ecosystem.

00:03:34.219 --> 00:03:37.519
And I think there are like
a couple of interesting.

00:03:38.410 --> 00:03:44.019
Things, you know, properties that
the web ecosystem has and things that
happened in the way web ecosystem that

00:03:44.019 --> 00:03:52.689
led to this, but, um, they, there's
just been a, um, a lot of innovation
and investment in, in web tooling.

00:03:53.010 --> 00:03:56.769
Um, and, you know, and people
complain about things like, oh,
my node, node_modules is too big.

00:03:56.959 --> 00:03:57.250
Right.

00:03:57.250 --> 00:04:04.679
But like, um, uh, there's just a lot of
people working on web tooling, um, and
doing really interesting things in it.

00:04:05.285 --> 00:04:12.605
And, um, you know, I think a lot of
that comes from, like, uh, React and
TypeScript being these two, like,

00:04:12.605 --> 00:04:20.265
hugely successful projects that had big
corporations behind them, and that, like,
attracted a lot, it became very cool,

00:04:20.595 --> 00:04:25.835
at least in, like, my world, I don't
know, it became very cool to, like, work
on web tooling, whereas I think when I

00:04:25.835 --> 00:04:32.040
was, like, in college, maybe, I think
like front end was like not as, um, it
didn't seem as like hardcore, right?

00:04:32.040 --> 00:04:35.089
It was like the trope, um,
whether it's true or not.

00:04:35.090 --> 00:04:36.700
I started my career doing front end.

00:04:37.390 --> 00:04:43.640
<c.speaker>Tim:</c> That's, that's pretty close to
being a designer, you know, like,
gosh, is that even real engineering?

00:04:44.570 --> 00:04:44.890
<c.speaker>Charlie:</c> Yeah.

00:04:44.890 --> 00:04:48.439
And it turns out it like really is, and
it's actually very hard and complex.

00:04:48.439 --> 00:04:50.530
And there's like a lot of
super interesting work to do.

00:04:50.530 --> 00:04:52.760
Like I've spent a lot of my
career doing front end actually.

00:04:52.840 --> 00:04:56.979
Um, but it was interesting to me
because there were just all these,
all these people going in and

00:04:57.029 --> 00:04:59.580
like, everyone's kind of working
on innovating and building tooling.

00:04:59.689 --> 00:05:02.320
Um, and, and, you know, the
other thing I noticed there was.

00:05:03.200 --> 00:05:09.780
They, in web, they just ran into
a lot of problems, like a lot of
performance, especially like local

00:05:09.789 --> 00:05:14.589
driven and development driven
performance problems, um, quickly.

00:05:14.599 --> 00:05:18.050
So like apps got bigger, and
you have like, bundling and

00:05:18.050 --> 00:05:21.349
transpilation and minification,
like all these things going on.

00:05:21.550 --> 00:05:26.320
So like, things are getting slower,
and so people started to build
like, Faster and faster tools.

00:05:26.350 --> 00:05:29.610
And in particular, they started to build
tools that were not written in JavaScript.

00:05:29.630 --> 00:05:32.050
They were like, okay, we're going
to build like foundational tooling

00:05:32.060 --> 00:05:35.130
in different languages to enable
everyone who's working in JavaScript.

00:05:35.829 --> 00:05:40.050
Um, and the first example I
always think of there is like
esbuild, which was written in Go.

00:05:40.340 --> 00:05:48.640
Um, Now there's like a whole proliferation
of tooling that's written in like Rust
and Go and Zig in in the web in the web

00:05:48.640 --> 00:05:55.170
ecosystem And so I kind of like saw all
that stuff happening in web and I was
like looking at Python And I was thinking

00:05:55.179 --> 00:05:58.809
like why isn't this really is there a
reason that it can't happen in Python?

00:05:58.830 --> 00:06:05.135
I guess would have been the question
and it was um You know, it was a time
in my life when I was kind of trying

00:06:05.135 --> 00:06:09.565
to figure out, I'd sort of, I'd left my
job and I was kind of trying to figure
out what I wanted to work on next.

00:06:09.915 --> 00:06:19.165
And, um, uh, you know, one of the
big pieces from that too was I,
um, I wanted to get better at Rust.

00:06:19.474 --> 00:06:22.724
That was like an honest, a very honest
motivation for starting to work on Rust.

00:06:22.735 --> 00:06:25.135
<c.speaker>Tim:</c> Yeah, I, I, I relate
to that very heavily.

00:06:25.195 --> 00:06:31.380
I, uh, sometimes say the reason I wrote
Rust in Action was to teach myself Rust

00:06:32.690 --> 00:06:33.490
<c.speaker>Charlie:</c> Yeah, exactly.

00:06:33.490 --> 00:06:33.960
I mean I

00:06:34.200 --> 00:06:35.980
<c.speaker>Tim:</c> Like take on some big audacious goal

00:06:37.235 --> 00:06:40.825
<c.speaker>Charlie:</c> Yeah, and I think I
wouldn't recommend this for everyone.

00:06:40.825 --> 00:06:44.415
But like for me, I think I kind of needed
to like build something from scratch.

00:06:44.735 --> 00:06:49.854
Um, and you know, in my previous job,
like we had a big Python monorepo and

00:06:49.855 --> 00:06:54.175
we started to move towards like a hybrid
Rust Python, uh, monorepo over time.

00:06:54.184 --> 00:06:56.515
So, um, and it was, but
I did not introduce that.

00:06:56.525 --> 00:07:02.440
It was one of my coworkers, brilliant,
engineer named Colin Fuller, um, and
he was like, I think we should start

00:07:02.440 --> 00:07:08.210
building some of our, like, performance
critical services, uh, in Rust, also get
like a lot more platform portability,

00:07:08.250 --> 00:07:14.640
much easier for us, because we were also
writing, we were also writing software
that we needed to run, um, like on

00:07:14.640 --> 00:07:19.000
Windows machines in particular, because
we had a wet, we had a wet lab and we
were building software for scientists,

00:07:19.010 --> 00:07:22.835
so we needed to run, to write, you
know, code that could be very portable.

00:07:22.915 --> 00:07:27.075
And then, uh, on the server, we were like
downloading like many terabytes of images

00:07:27.075 --> 00:07:29.965
and we had like a lot of performance
critical routines we were doing there.

00:07:30.655 --> 00:07:32.905
So Rust turned out to be like
a really good fit for us.

00:07:32.925 --> 00:07:37.185
And the Rust Python interoperability
story was also very good.

00:07:37.805 --> 00:07:39.315
So we were using Py03.

00:07:39.475 --> 00:07:41.495
So we were writing all this
stuff in Rust, exposing it.

00:07:42.785 --> 00:07:44.465
over py03 on the Python side.

00:07:44.465 --> 00:07:47.095
So from, from the Python perspective,
we were kind of just like, you know,

00:07:47.435 --> 00:07:50.735
calling, calling functions and under
the hood, it was all written in Rust.

00:07:50.845 --> 00:07:54.785
Um, and so that was like
my first brush with Rust.

00:07:54.835 --> 00:07:58.645
Um, and the thing is like, you're at
a startup and you have like so many

00:07:58.645 --> 00:08:03.010
responsibilities, so like, I never
really learned Rust in that setting.

00:08:03.030 --> 00:08:06.460
Like I was always, you know, I was
going in like making contributions and

00:08:06.460 --> 00:08:10.520
fixing issues, but I was just trying to
get in and out as quickly as possible.

00:08:10.869 --> 00:08:15.809
And like the Rust paradigm is just,
um, I mean, I continue to believe like

00:08:15.829 --> 00:08:18.859
the learning curve for Rust is very
high, especially coming from Python.

00:08:18.859 --> 00:08:24.700
Like most of my career, by the way,
like, I mean, professionally, I mean, the

00:08:24.700 --> 00:08:27.980
closest thing I've done professionally
is like I wrote Java for a year, right?

00:08:28.020 --> 00:08:35.150
But most of my career has been like Python
and TypeScript and I'm not like a I'm not
a systems programmer by background at all.

00:08:36.409 --> 00:08:40.559
So it was just a lot of new very
new ways of thinking for me.

00:08:41.999 --> 00:08:47.430
I found like again coming back to why
I started talking about this in the
first place is that Like, one of the

00:08:47.430 --> 00:08:50.890
reasons I wanted to build Ruff was
like, I think I need to learn Rust.

00:08:50.910 --> 00:08:53.650
And I think to really learn Rust, I
need to build something from scratch.

00:08:53.910 --> 00:08:56.460
And the way that I like
to learn is just by doing.

00:08:56.810 --> 00:09:00.790
Um, and, I just know, you know,
and then I just spend a few days

00:09:00.790 --> 00:09:03.410
like, banging my head against
the wall trying to understand.

00:09:03.780 --> 00:09:09.370
The borrow checker, you know, and
like I was working with an AST, like
tree structures are like particularly,

00:09:10.060 --> 00:09:13.999
I guess, like, I don't know about
annoying, but like, you know, it can
be a little bit more challenging.

00:09:14.000 --> 00:09:18.810
And so I just spent a lot of time
trying to understand lifetimes and
trying to understand what am I doing?

00:09:19.300 --> 00:09:28.480
And, um, uh, you know, I think like at
some point, I think like the, one of
the first levels of like Rust, one of

00:09:28.480 --> 00:09:37.295
the first milestones I saw in myself
was, I knew, um, I wrote some code and
I actually knew it wouldn't compile.

00:09:37.620 --> 00:09:38.500
And I knew why.

00:09:38.770 --> 00:09:42.720
And like, I didn't really know how
to fix it, but I knew what the,
I knew what the error would be.

00:09:43.030 --> 00:09:47.400
Like, that's like a one level of
understanding, which is like, you
don't quite know like what the solution

00:09:47.400 --> 00:09:50.040
should look like, but like, okay, I
know what I'm doing here is not right.

00:09:50.050 --> 00:09:51.420
And I like, I, I know why.

00:09:51.750 --> 00:09:57.564
<c.speaker>Tim:</c> I've heard that, I think, in a
different context, which is that, um,
one of the really big distinguishing

00:09:57.564 --> 00:10:03.515
characteristics between someone that
is, I'd say, let's say an intermediate
or, you know, starting, very few

00:10:03.515 --> 00:10:06.825
people would be comfortable to say
that they are expert Rust programmers.

00:10:07.104 --> 00:10:08.075
I think that's probably the case.

00:10:08.075 --> 00:10:10.015
<c.speaker>Charlie:</c> Yes, I would absolutely not
say I'm an expert Rust programmer.

00:10:10.025 --> 00:10:14.845
<c.speaker>Tim:</c> Um, and, but one of the indicators
of someone that has proficiency

00:10:14.964 --> 00:10:22.504
is that they are much faster at
diagnosing and like remedying errors.

00:10:22.814 --> 00:10:25.264
Um, it's not to say
that they actually have.

00:10:26.130 --> 00:10:36.620
They write fast, or sorry, write better
code straight away, it's just that when
they encounter problems they, their

00:10:36.620 --> 00:10:42.900
brain is slightly more attuned to the
signals that the compiler is going,
or it's like something kind of seems

00:10:42.900 --> 00:10:48.290
a little bit iffy with the control
flow here, and so I think that the
borrow trigger is going to complain.

00:10:49.610 --> 00:10:49.920
Yeah.

00:10:51.670 --> 00:10:55.160
And so that's, that, that it's interesting
to see that, that come through.

00:10:55.670 --> 00:11:04.210
I was wondering, and I don't want
to put you on the spot too much,
but how do you explain lifetimes?

00:11:05.510 --> 00:11:09.640
Like if someone comes to say, Oh, I'm
a TypeScript developer, I'm interested

00:11:09.640 --> 00:11:13.820
in Rust, but I'm really, these
things don't make any sense to me.

00:11:16.395 --> 00:11:23.475
<c.speaker>Charlie:</c> I feel like my answer to that
would actually be like I Won't I won't

00:11:23.515 --> 00:11:26.255
actually answer the question because I
don't know if I've ever actually had to

00:11:26.264 --> 00:11:26.634
...
<c.speaker>Tim:</c> Okay.

00:11:26.955 --> 00:11:31.125
<c.speaker>Charlie:</c> ...but I think but one thing
I'd think about with Rust and maybe
I'll try and tie us back to an answer

00:11:31.655 --> 00:11:41.925
is like I do think that that if you
I think if you just like dive in to
like expertly written Rust or expose

00:11:41.925 --> 00:11:49.415
yourself actually to like too much of
the language,  I actually think it's like
not that helpful like I wrote just an

00:11:49.415 --> 00:11:58.404
example like I wrote so much Rust code
before I actually used even like Box<_>.

00:11:58.724 --> 00:11:58.984
<c.speaker>Tim:</c> Yeah.

00:11:59.134 --> 00:12:03.105
<c.speaker>Charlie:</c> Like you can just write like
a lot of and if you you know If you get
dropped into Rust code something you

00:12:03.105 --> 00:12:08.510
see like, okay, I got like box sure fine
Then I've got like Rc and I've got Arc

00:12:08.510 --> 00:12:12.220
and I've got like RefCell and like you
kind of get exposed to all this stuff.

00:12:12.430 --> 00:12:16.629
Um, even like lifetimes like you can get
pretty far explicit lifetimes at least

00:12:16.629 --> 00:12:20.030
like you can get pretty far without like
actually using any explicit lifetimes.

00:12:20.390 --> 00:12:31.430
Um, and it, it's funny because I think
if you see all that stuff like If you
see like Rc and, and I mean it's fine

00:12:31.440 --> 00:12:36.240
to like use this stuff, sure, but like
sometimes you see things and you're
like, okay, I have a problem in my

00:12:36.240 --> 00:12:41.130
code and like I kind of Google, uh,
you know what, what the problem is.

00:12:41.130 --> 00:12:43.749
It's like, I need to
be able to mutate this.

00:12:43.790 --> 00:12:46.050
Um, I don't know what's a good example.

00:12:46.069 --> 00:12:49.330
It's like, I need to be able
to like mutate this thing
without marking it as mut.

00:12:49.685 --> 00:12:50.135
Right?

00:12:50.505 --> 00:12:53.765
And so then people are like, Oh, like
you should use like RefCell, right?

00:12:53.765 --> 00:12:54.485
Like blah, blah, blah.

00:12:54.715 --> 00:12:56.625
But, and like, that
actually might be right.

00:12:57.025 --> 00:13:00.775
But often when you hit problems in Rust,
I find that you're thinking about that.

00:13:00.784 --> 00:13:03.055
You're actually thinking about
the problem in the wrong way.

00:13:03.114 --> 00:13:05.194
Like, like someone else
should own the data, right?

00:13:05.204 --> 00:13:08.044
Or like the, or like it should
be passed in in some other way.

00:13:08.405 --> 00:13:16.504
And so I found that like, it was actually
helpful for me to like, ignore a lot of
that stuff and like, and it's not like

00:13:16.505 --> 00:13:21.460
I was like that smart about it, but
I was like, It was helpful for me to,
like, ignore some of that stuff and,

00:13:21.460 --> 00:13:25.570
like, try to, try to, like, uh, force
myself to learn things without reaching

00:13:25.570 --> 00:13:31.160
for some of those more advanced tools,
um, in order to learn, to learn Rust.

00:13:31.410 --> 00:13:32.710
<c.speaker>Tim:</c> Totally agree with you.

00:13:32.790 --> 00:13:41.050
There is a very, I find this, one
of the other things is that you
encounter an issue and you sort of

00:13:41.050 --> 00:13:43.840
had this decision paralysis, it's
like, well, how do I fix this?

00:13:44.150 --> 00:13:49.015
And maybe pausing and thinking about
how the code is structured and saying,

00:13:49.015 --> 00:13:53.315
well, actually we want one unique place
that has responsibility for cleanup.

00:13:54.485 --> 00:13:54.975
<c.speaker>Charlie:</c> Right, right.

00:13:55.315 --> 00:13:56.995
<c.speaker>Tim:</c> And how do we enable that?

00:13:57.194 --> 00:14:02.625
Like how we could use a fancy smart
pointer or we could tweak our code.

00:14:03.004 --> 00:14:09.515
And, um, yeah, I, I, I like that idea
actually of saying, don't be intimidated

00:14:09.545 --> 00:14:16.295
by, um, the very advanced stuff that's,
you know, at like the 99th percentile.

00:14:17.574 --> 00:14:22.995
Actually, you could probably stay in
the 50th percentile for a long time.

00:14:23.974 --> 00:14:24.704
<c.speaker>Charlie:</c> I think you can.

00:14:24.734 --> 00:14:25.134
Yeah.

00:14:25.364 --> 00:14:28.754
And like, and in the context that
you're writing code in, like, I don't

00:14:28.754 --> 00:14:32.564
know, I've become like allergic to a
lot of things from working on ruff.

00:14:32.584 --> 00:14:34.214
Like, I'm very allergic to cloning.

00:14:34.709 --> 00:14:36.900
Like probably too much,
you know what I mean?

00:14:36.910 --> 00:14:42.540
Like now, like we have ruff and we
have UV now, which is like a, it's
sort of like a pip alternative.

00:14:42.550 --> 00:14:47.310
It's a Python package installer, um,
and resolver, uh, written in Rust.

00:14:47.919 --> 00:14:51.959
And like in UV, a lot of the
dynamics are really different
because there's like way more IO.

00:14:52.419 --> 00:14:56.240
Um, like we're downloading
packages and like zipping, right.

00:14:56.240 --> 00:14:57.040
And like blah, blah.

00:14:57.040 --> 00:15:02.435
And so like cloning is actually like,
not nearly as much of a big deal.

00:15:02.965 --> 00:15:08.445
Um, whereas in rough, if we're, if
we do like a lot of, a lot of cloning
or a lot of allocations in a hot,

00:15:08.565 --> 00:15:13.435
in a hot path, like it immediately
shows up in all the performance
profiles, like it's very obvious.

00:15:14.025 --> 00:15:17.175
Um, and so like ruff kind of
trained me in a certain way.

00:15:17.469 --> 00:15:23.269
Um, and it's funny because now I work
on UV and like I have people on the
team who are like complaining about

00:15:23.279 --> 00:15:28.909
all the lifetimes They're like you
should all just be RC or like blah
blah blah or like we should just clone

00:15:28.909 --> 00:15:32.180
here or like blah blah And like they're
actually they're actually right.

00:15:32.389 --> 00:15:38.249
Like I think I have like over rotated
on some of the things I learned
from working on ruff But it's been

00:15:38.249 --> 00:15:44.765
interesting but like yeah again, I
think Like, you can clone your way
out of problems if you're learning

00:15:44.765 --> 00:15:48.715
Rust, right, as a way to get yourself
to move along, I think, sometimes.

00:15:48.785 --> 00:15:53.564
Um, and maybe the expert level solution
lets you avoid some of those allocations,
but like, often it won't really matter.

00:15:54.405 --> 00:15:54.834
<c.speaker>Tim:</c> Sure.

00:15:54.984 --> 00:16:03.604
Hey, I was wondering if we could
segue slightly back to, uh, your
career and some of the things that

00:16:03.734 --> 00:16:08.804
you did beforehand, because there's
an overarching suspicion that I have.

00:16:08.804 --> 00:16:13.144
I've got a couple of assumptions
about the kind of person that you are.

00:16:13.554 --> 00:16:22.604
Um, so the, uh, and I just want to
essentially either validate that, um,
Because it seems like a lot of the

00:16:22.604 --> 00:16:31.724
decisions that you've made have been
very centric, uh, very, you're, you're,
you, correct me if I'm wrong, but you

00:16:31.724 --> 00:16:36.155
worked at a health science, uh, machine
learning startup for diagnostics.

00:16:36.245 --> 00:16:41.734
Um, and, uh, before that you
worked at the Khan Academy.

00:16:42.584 --> 00:16:42.974
<c.speaker>Charlie:</c> That's right.

00:16:43.194 --> 00:16:50.844
<c.speaker>Tim:</c> And that implies to me that
you've had other people at the
front of mind for a long time.

00:16:51.124 --> 00:17:01.194
And, and I don't want to be too prejudiced
against, uh, so I'm gonna, and, but you,
I saw that your undergraduate at least

00:17:01.194 --> 00:17:05.994
is at Princeton, but you probably made a
deliberate choice not to do grad school.

00:17:06.034 --> 00:17:06.805
Was that correct?

00:17:07.865 --> 00:17:08.654
<c.speaker>Charlie:</c> Yeah, that's right.

00:17:08.814 --> 00:17:09.024
Yeah.

00:17:10.254 --> 00:17:11.494
<c.speaker>Tim:</c> So do you want to talk me through

00:17:11.914 --> 00:17:14.744
...
<c.speaker>Charlie:</c> ...that career path and
why I made these various decisions?

00:17:14.744 --> 00:17:15.214
Yeah.

00:17:15.885 --> 00:17:16.844
Yeah, yeah, of course.

00:17:16.895 --> 00:17:23.020
Um, well, I, uh, I interned at Khan
Academy, um, after my junior year

00:17:23.020 --> 00:17:31.979
of college and, um, that, uh, that
experience was just really, really good.

00:17:32.590 --> 00:17:32.910
<c.speaker>Tim:</c> Cool.

00:17:32.950 --> 00:17:36.760
<c.speaker>Charlie:</c> And so, um, uh, you know, I
wanted, it was, it was pretty clear
to me that I wanted to go back and

00:17:36.760 --> 00:17:43.210
join full time, but I think the things
that made that, um, uh, a really
appealing decision to me, you know,

00:17:43.210 --> 00:17:49.120
one was, um, I try and a lot of these
career decisions, um, around impact.

00:17:49.405 --> 00:17:55.275
So what are things I can do
to have a significant positive
impact on, on people in the world?

00:17:55.335 --> 00:17:59.555
Um, and uh, Khan Academy is something
that I had used, um, you know, a lot.

00:17:59.564 --> 00:18:01.974
It was really helpful for
like, for my own education.

00:18:02.015 --> 00:18:07.765
Um, and so the opportunity to go and work
there in terms of like impact, you know,
was really, um, really appealing to me.

00:18:08.260 --> 00:18:14.630
Um, you know, the other pieces to
it were, um, Khan Academy, um, had

00:18:14.630 --> 00:18:18.070
a really, really strong engineering
team and engineering culture.

00:18:18.500 --> 00:18:23.010
And so like most of the
things, like, I think.

00:18:23.780 --> 00:18:26.500
Khan Academy is where I learned,
you know, at least for one

00:18:26.500 --> 00:18:29.790
definition, like what it means to
be like a great software engineer.

00:18:29.820 --> 00:18:34.640
Like, I don't think it was necessarily me
at that point in time, but like I got to
work with a lot of really amazing people.

00:18:35.070 --> 00:18:39.209
<c.speaker>Tim:</c> I can't believe that you are
not a person who believes that they

00:18:39.209 --> 00:18:42.820
were, you know, a 10X developer,
um, in their very first gig.

00:18:43.200 --> 00:18:46.450
<c.speaker>Charlie:</c> I think I was a good, I
think I was a good software engineer,
but I was also pretty young, right?

00:18:46.450 --> 00:18:49.200
And I was also learning
and everything was new.

00:18:49.680 --> 00:18:52.550
But like, you know, the,
just the quality of people.

00:18:52.580 --> 00:18:54.360
<c.speaker>Tim:</c> So what's it like, the culture?

00:18:54.389 --> 00:18:56.030
So you said they have a
strong engineering culture.

00:18:56.040 --> 00:18:57.580
Is it 100 percent remote?

00:18:57.699 --> 00:19:00.560
Is it all, uh, in a building?

00:19:00.680 --> 00:19:01.360
<c.speaker>Charlie:</c> This is a while ago.

00:19:01.360 --> 00:19:03.149
This is like 2015, 2016.

00:19:03.150 --> 00:19:04.389
So it's a while ago at this point.

00:19:04.400 --> 00:19:06.899
But at that point in time,
it was about a third remote.

00:19:06.950 --> 00:19:09.070
The rest was in Mountain
View in California.

00:19:09.580 --> 00:19:14.760
Um, and there were just some really,
yeah, some really amazing people
who kind of anchored a lot of the

00:19:14.760 --> 00:19:19.230
culture, like, um, like Ben Kamens,
who is the VP of engineering.

00:19:19.230 --> 00:19:24.039
And then he went on to found the company
that I joined after Khan Academy,
which is how I got, how I got sort

00:19:24.040 --> 00:19:27.740
of roped into, um, that, which is,
you know, we can talk about that too.

00:19:27.810 --> 00:19:35.440
Um, uh, uh, John Resig, who's like
the creator of jQuery, um, still
at Khan Academy, I think, um, Craig

00:19:35.440 --> 00:19:41.330
Silverstein, who was like the, The
first employee at Google and then
joined, he's just like, it's incredible.

00:19:41.340 --> 00:19:47.879
Software engineer, um, Sophie Alpert,
who was like for a long time, the
number one committer to react outside

00:19:47.879 --> 00:19:50.930
of Meta and then joined React and
manage the React team eventually.

00:19:50.930 --> 00:19:53.539
So it was just like a very, very
high quality group of people.

00:19:53.899 --> 00:19:59.780
Um, and there was a lot of, um, emphasis
just put on, on, you know, on the culture.

00:19:59.790 --> 00:20:02.980
And I think I, I think everything from
like our career development guide.

00:20:04.090 --> 00:20:08.610
I just learned so much by looking at
like what is this company value and
like what are the traits that someone

00:20:08.620 --> 00:20:12.129
has that demonstrates that they
are, for example, a senior engineer?

00:20:12.129 --> 00:20:13.999
Like what does it mean to be able to own?

00:20:14.299 --> 00:20:16.899
What is, what is this concept of
ownership that people keep talking about?

00:20:16.899 --> 00:20:25.135
And it just really helped me understand,
um, uh, you know, the, the, uh, I had a
lot of role models, I think, is what I'll

00:20:25.135 --> 00:20:31.475
say, and I had, it was a very good setting
for me to kind of grow and, and, and, and
learn how to be, um, a better software

00:20:31.475 --> 00:20:34.715
engineer and not just technically, but
in terms of taking on more ownership and

00:20:34.725 --> 00:20:39.475
being, um, growing my maturity, um, my
ability to execute on large projects.

00:20:39.994 --> 00:20:41.575
Um, but I worked..

00:20:41.695 --> 00:20:42.355
<c.speaker>Tim:</c> Software.

00:20:42.535 --> 00:20:43.615
Oh, sorry, excuse me.

00:20:44.160 --> 00:20:46.120
<c.speaker>Charlie:</c> Was just gonna say I
worked like all over the stack

00:20:46.120 --> 00:20:50.070
there because I started I started
doing like mostly doing front end.

00:20:50.070 --> 00:20:53.410
We were like a really big React
company, which is I guess everyone

00:20:53.410 --> 00:20:57.210
is now sort of but like that was a
little bit less the case at the time.

00:20:58.499 --> 00:21:02.120
You know, I did like I worked on
our first like iOS apps a bit.

00:21:02.130 --> 00:21:04.220
I did like a year of Android, too.

00:21:04.325 --> 00:21:05.885
<c.speaker>Tim:</c> Oh, which is where
you would have done Java.

00:21:05.905 --> 00:21:06.635
<c.speaker>Charlie:</c> Yeah, exactly.

00:21:06.645 --> 00:21:06.905
Yeah.

00:21:06.905 --> 00:21:12.145
And then, and then our, our backend
was all Python and we were like, we
just had like a huge Python code base.

00:21:12.175 --> 00:21:18.335
Um, uh, and so I kind of got exposed
to, you know, all those different
uh, parts of the development stack.

00:21:18.889 --> 00:21:25.430
Um, which, so for me, it was like kind
of the perfect place to be an engineer
starting out my career and, and I still

00:21:25.760 --> 00:21:32.460
lean on a lot of the things I learned
there about like being a, being a great
and productive engineer, um, today,

00:21:32.470 --> 00:21:35.389
especially as I'm looking at, like, how
do we define our own culture as a company?

00:21:35.659 --> 00:21:42.289
<c.speaker>Tim:</c> Yeah, I mean, that must be
quite intimidating because it's a
significantly different set of skills,

00:21:42.629 --> 00:21:48.100
essentially being asked to be the senior
leader, especially in a small company.

00:21:48.800 --> 00:21:54.820
And you're founding this from
the east coast of the United
States, outside of Mountain View.

00:21:54.879 --> 00:21:55.489
<c.speaker>Charlie:</c> That's right, yep.

00:21:55.800 --> 00:21:59.370
<c.speaker>Tim:</c> Most people are building software
companies outside of Silicon Valley.

00:22:01.429 --> 00:22:09.625
So, do you have any, you know, like,
pearls of wisdom, or any bits and pieces
for people that are kind of, maybe at

00:22:09.625 --> 00:22:15.075
a four to nine people, you know, like
sub 10 individual company that are

00:22:15.145 --> 00:22:20.645
growing healthily to really set that
foundation for like the next 10 years.

00:22:21.164 --> 00:22:24.194
<c.speaker>Charlie:</c> So for us, um,
yeah, I'm based in New York.

00:22:24.204 --> 00:22:28.544
Our team is nine full
time, um, including me.

00:22:28.704 --> 00:22:35.744
Um, and no, like no two
people live in the same state.

00:22:36.225 --> 00:22:40.020
Um, and outside the US, no two
people live in the same country.

00:22:40.020 --> 00:22:46.379
So like we have about half the teams
in the US, half the team is, um, is,
uh, international outside the US.

00:22:46.669 --> 00:22:55.395
Um, and we span time zones from,
Pacific through to, um, IST, like,
uh, Bangalore would be the furthest.

00:22:56.155 --> 00:22:58.155
So like, it's a very large range of time.

00:22:58.155 --> 00:22:58.305
So...

00:22:58.855 --> 00:23:01.045
<c.speaker>Tim:</c> I'm sure your accountant
is very happy with you.

00:23:01.054 --> 00:23:01.424
<c.speaker>Charlie:</c> Yeah.

00:23:01.644 --> 00:23:09.275
Um, it has that, I think it's sort of like
the least of the challenges, but yeah,
that is, that is one of the challenges.

00:23:09.715 --> 00:23:13.065
Um, I mean, I think for us, like
the main thing that the main things

00:23:13.065 --> 00:23:18.355
I focused on are one, um, we've
grown this team very deliberately.

00:23:18.689 --> 00:23:29.280
So like, um, you know, I think in
March of last year, uh, that was when
I first hired anyone apart from myself.

00:23:29.280 --> 00:23:32.629
And we grew, I hired two people, like
in March we grew from one to three.

00:23:32.939 --> 00:23:36.199
And then from, from March, so over the
past, you know, a little over a year,

00:23:36.199 --> 00:23:39.610
we grew from like three to nine and,
you know, it was incremental, right?

00:23:39.610 --> 00:23:44.405
It was like, One month we had four,
and then two months later we had five,
and then a few months later we had six.

00:23:44.625 --> 00:23:50.884
Um, and, you know, even like three
to six to nine, those are all
like really different companies.

00:23:50.885 --> 00:23:56.995
Um, yeah, and so everyone's like,
you know, some people are rolling
their eyes being like nine is not a

00:23:56.995 --> 00:24:02.675
big company, but like, if you were
three, then like suddenly nine just,
you know, like a lot of the processes

00:24:02.685 --> 00:24:05.105
that you put in place when you
were three like don't work anymore.

00:24:05.415 --> 00:24:11.745
Um, and so, being flexible about
how you change, like how you
work, I think is really important.

00:24:11.835 --> 00:24:16.115
Um, yeah, I think one of the main
things that we've tried to focus
on, especially being a distributed

00:24:16.115 --> 00:24:21.805
company, is, um, uh, And it sounds
cliche, but I'll give some examples.

00:24:21.855 --> 00:24:26.045
Like, I think in order to work
effectively, like, asynchronously,

00:24:26.550 --> 00:24:30.010
You have to have a team that really
like trusts each other a lot.

00:24:30.510 --> 00:24:37.810
Um, and my favorite example of trust
or a very concrete example of the thing
that we try to do is like, If you're

00:24:37.810 --> 00:24:43.140
reviewing someone's pull request and
you think it's close, but you want some
things to change, like approving it

00:24:43.140 --> 00:24:49.789
with feedback rather than like leaving
comments or requesting changes is
like a way more effective thing to do.

00:24:50.359 --> 00:24:55.869
Um, because it can save like a whole day
in turnaround time, because imagine you
get some comments, then you go to sleep,

00:24:55.870 --> 00:24:59.269
they wake up, they address the comments,
you wake up, eventually you approve it.

00:24:59.269 --> 00:25:01.339
They're asleep then they
wake up and merge it.

00:25:01.339 --> 00:25:01.589
<c.speaker>Tim:</c> Right.

00:25:01.819 --> 00:25:06.040
So like, But that requires trust,
like you have to be able to trust

00:25:06.050 --> 00:25:09.810
and have good norms and establish
norms around, if I give feedback.

00:25:10.534 --> 00:25:13.264
<c.speaker>Charlie:</c> First of all, I know
that they're actually going to
look at it, take it seriously.

00:25:13.294 --> 00:25:17.135
They don't have to address it, but
I can trust that if they don't, they

00:25:17.135 --> 00:25:20.054
will at least consider it and have good
reasons for, for not addressing it.

00:25:20.054 --> 00:25:21.185
And they will tell me why.

00:25:21.485 --> 00:25:27.254
So like trying to build a culture
that's really based on trust, I think, I
think if you like have a culture that's

00:25:27.254 --> 00:25:32.915
really based on distrust, um, or, uh,
or not, or, or at least not based on
trust, the alternative is very bad.

00:25:32.915 --> 00:25:33.075
<c.speaker>Tim:</c> Yeah.

00:25:33.075 --> 00:25:34.855
The alternative is unhealthy, right?

00:25:34.865 --> 00:25:36.294
<c.speaker>Charlie:</c> And also I just think way harder.

00:25:36.515 --> 00:25:43.445
Like, it's hard to work asynchronously
effectively, um, you have to be able to
trust people to like make good responsible

00:25:43.445 --> 00:25:49.905
decisions and also be respectful of,
uh, you know, the feedback you give
and, uh, and, and your own opinions.

00:25:50.175 --> 00:25:53.394
So, um, that's been a really
important thing for us.

00:25:53.415 --> 00:26:02.155
<c.speaker>Tim:</c> That is a very hard thing to
maintain and it's much harder when you,
if you don't start in the right place.

00:26:03.495 --> 00:26:07.235
And I can speak from my experience
of working at a very large company.

00:26:08.850 --> 00:26:12.860
When essentially individual teams
or individual departments are almost

00:26:12.860 --> 00:26:18.110
at war with each other because
of the way that the metrics work.

00:26:19.129 --> 00:26:27.299
Essentially, you lose a lot of faith
that the people outside of your sphere of
influence have your interests at heart.

00:26:27.340 --> 00:26:33.050
Whereas it's nice to know that Our
colleagues really care about the product.

00:26:33.050 --> 00:26:35.350
We really care about our
customers and our users.

00:26:35.929 --> 00:26:37.810
Uh, so that's, that's really positive.

00:26:37.810 --> 00:26:44.610
One of the other things though,
approving with comments, I like that
approach, but I did have one instance

00:26:44.610 --> 00:26:51.050
in my career when people had one, I
suppose, yeah, I guess we call him

00:26:51.050 --> 00:26:55.740
my manager, uh, engineering manager,
let's say he would always approve.

00:26:56.800 --> 00:27:01.830
But sometimes it would be like
a tacit, like a very like,
but this needs to change.

00:27:01.909 --> 00:27:07.899
And I was of the opinion, I was like,
actually, if you need significant
refactoring, I would rather that you

00:27:07.899 --> 00:27:16.520
hit the changes required button because
that like sets me up with this mental
model of, oh, okay, so that's fine.

00:27:16.860 --> 00:27:18.139
You're being honest with me.

00:27:18.490 --> 00:27:27.814
Um, that's another way of, um,
Uh, I, I think respecting the
protocol and like, not being afraid.

00:27:27.894 --> 00:27:31.194
I like rejection is a very, very,
like, I don't think I've ever had a

00:27:31.194 --> 00:27:37.814
PR explicitly said someone said no
to, but, um, this does not make, but

00:27:39.364 --> 00:27:45.154
<c.speaker>Charlie:</c> I mean, if you've contributed
to open source, you probably have at
some point, but yeah, no, I don't.

00:27:48.169 --> 00:27:53.090
It's much more likely that your patch is
just going to sit there for a long time.

00:27:53.479 --> 00:28:01.229
<c.speaker>Tim:</c> Um, so do you want to talk
me through the relationship with
Zip VC funding and open source?

00:28:01.549 --> 00:28:04.600
Because this must have been something
you've thought about personally.

00:28:04.934 --> 00:28:07.944
And, um, I'm, I'm, I'm really
interested in your take.

00:28:08.034 --> 00:28:08.724
<c.speaker>Charlie:</c> Yeah, totally.

00:28:08.784 --> 00:28:11.724
Can I react to the thing you were saying
before though, quickly before we...

00:28:11.814 --> 00:28:12.174
<c.speaker>Tim:</c> Oh, sure.

00:28:12.324 --> 00:28:12.634
<c.speaker>Charlie:</c> Yeah.

00:28:12.844 --> 00:28:19.974
So I think like, um, a few things on the,
like, it's actually helpful when people
request changes, like that general theme.

00:28:20.424 --> 00:28:22.674
Um, first of all, yeah, definitely.

00:28:22.694 --> 00:28:27.964
Like, I think there's a lot
of, um, implicit norms that
get like established on a team.

00:28:28.324 --> 00:28:34.115
Um, and I, I think if you, if someone
puts up a PR and, you know, There's
actually like important like discussion

00:28:34.115 --> 00:28:40.764
or dialogue to be had about some of
the core decisions, then you should not
approve it But part of it is like well,

00:28:40.764 --> 00:28:45.924
like you should you should signal that
like hey, this is what I'm thinking about
blah blah Sometimes it can be a sign of

00:28:45.924 --> 00:28:52.635
process failure I think if you like get
to a PR and there's like a significant
disagreement about design Sometimes it

00:28:52.635 --> 00:28:58.715
depends like what the PR is supposed to
be and what you're trying to accomplish
with it But but but another part here

00:28:58.715 --> 00:29:02.985
is like If you're gonna build a culture
that's based on trust, like, you start

00:29:02.985 --> 00:29:06.074
with a certain level of trust, but then
it needs to be, like, built up over time.

00:29:06.334 --> 00:29:10.975
So, like, you sh part of it
is, like, we assume good intent
and we assume trust to start.

00:29:11.570 --> 00:29:15.510
There are things you can do to, like,
lose people's trust, and there are things
you can do to, like, build people's

00:29:15.510 --> 00:29:22.179
trust up further, and so, you know,
early on, like, we might, um, start
with a certain tolerance or a certain

00:29:22.179 --> 00:29:26.139
level of, like, we're gonna prove this
with feedback, or, like, we're gonna,
let's have some discussion about blah,

00:29:26.139 --> 00:29:31.499
blah, and, like, use some of these as
learning opportunities, um, but, but
I guess for us it's, like, start from

00:29:31.499 --> 00:29:34.759
a high degree of trust and try to,
like, build it up over time, and when

00:29:34.759 --> 00:29:38.860
we see people lose trust, then try to
figure out ways that we can restore it.

00:29:40.120 --> 00:29:50.759
<c.speaker>Tim:</c> Yeah, sure, because I guess
trust tends to neutral over time
with like a lack of intervention.

00:29:50.969 --> 00:29:57.959
I can see that happening on both angles
in relationships where there might have
been a significant disagreement, well

00:29:57.959 --> 00:30:02.195
one of the You know, common patterns
is that people will essentially not

00:30:02.205 --> 00:30:04.715
talk to each other for a couple of
months and then be able to come back.

00:30:04.715 --> 00:30:09.884
It doesn't work so much in an
organizational setting, but, um, Are

00:30:09.885 --> 00:30:14.955
you actively looking for signals that
trust is being maintained between?

00:30:15.450 --> 00:30:16.070
Your stuff.

00:30:16.070 --> 00:30:22.500
I mean, I don't probably, I don't want to
peer too much into the company, but, um,
that, that would be kind of interesting.

00:30:22.570 --> 00:30:23.150
<c.speaker>Charlie:</c> I do.

00:30:23.150 --> 00:30:23.350
Ya.

00:30:23.610 --> 00:30:28.589
I mean, I look at like, I mean, the funny
thing is, right, that, like, we're remote.

00:30:28.590 --> 00:30:32.100
So like most of our, like almost
all of our activity and interaction,

00:30:32.749 --> 00:30:37.680
um, I mean, a very, very large
portion of it is like fully public.

00:30:38.140 --> 00:30:42.890
Um, because we don't have, we have
one private Git repo and it's our

00:30:42.990 --> 00:30:46.950
company website and everything
else that we do is public, right?

00:30:46.990 --> 00:30:54.119
And, um, we developed UV, that was
a private repo from like October to
February and then we released it.

00:30:54.420 --> 00:30:58.080
But like the whole Git history and all
that discussion, everything is there.

00:30:58.470 --> 00:31:04.390
Um, and then, uh, so like a lot of
what we do is just like fully public.

00:31:04.780 --> 00:31:09.100
And then, um, you know, all of our
internal communications, they're private

00:31:09.110 --> 00:31:11.900
to outside the company, but you know,
it's all public within the company.

00:31:12.180 --> 00:31:16.530
Um, so like, uh, because we're
distributed, it's just like, there's a

00:31:16.530 --> 00:31:20.789
lot of visibility into like what, how,
how people are engaging and, and all that.

00:31:20.829 --> 00:31:28.900
Um, and you know, I look at, I, I, I
think like being a leader, a lot of it's
like trying to pick up on small signals.

00:31:29.170 --> 00:31:29.410
Right.

00:31:29.410 --> 00:31:34.090
So like looking at how, and not in
a way where I'm like snooping on
people, but like, okay, when people

00:31:34.090 --> 00:31:39.460
engage in a PR, like what's going
on, like someone requested changes
or like, was that reasonable?

00:31:39.460 --> 00:31:40.559
Like, how do I think about that?

00:31:40.559 --> 00:31:44.409
And then, um, or like, are they
treating these different people on

00:31:44.410 --> 00:31:48.499
the team fairly, or like, did this
person, uh, take this feedback well?

00:31:48.500 --> 00:31:53.220
And, and, and so I do like look at all
that stuff and I think about it and I
talk about it with people on the team.

00:31:53.260 --> 00:31:59.725
Um, and then I guess the other piece,
it's a little bit different, but like, I
don't know, sometimes I try and do things,

00:31:59.775 --> 00:32:06.105
maybe this is stupid, but like, sometimes
I try and do things to like exhibit
behaviors that I think are good, um,

00:32:08.205 --> 00:32:08.585
yeah.

00:32:08.585 --> 00:32:10.845
<c.speaker>Tim:</c> Yeah, look, I think
modeling is important, right?

00:32:11.065 --> 00:32:15.065
As long as it isn't you attempting to
project something that doesn't exist.

00:32:15.294 --> 00:32:22.310
And it strikes me that you're
actually projecting, you're
exhibiting the way that, you know,

00:32:22.310 --> 00:32:28.750
some idealized state, potentially,
but, um, but that's, that's okay.

00:32:28.900 --> 00:32:29.759
You can create.

00:32:29.860 --> 00:32:31.920
You're not going against
the grain, really.

00:32:31.929 --> 00:32:33.679
You're just kind of reinforcing.

00:32:34.099 --> 00:32:38.819
It's interesting to hear that, you
know, sometimes you will go and
read the comments, and I think this

00:32:38.820 --> 00:32:45.289
is really important whenever I've
supervised or met with people, or even
when I've gone for a promo, promotion.

00:32:46.235 --> 00:32:48.755
I've had feedback at like interview loops.

00:32:48.765 --> 00:32:54.185
It's like, oh, no, no, we've, we've
looked through your interactions
and they're really, really positive.

00:32:54.875 --> 00:32:59.694
So that's, uh, a really good sign for
us that you'll be a good fit for the

00:32:59.695 --> 00:33:04.115
team because when there are changes that
you'd like, you're very, uh, tactful.

00:33:04.144 --> 00:33:10.425
And so that's, um, so just, just a
hint, I suppose, to everyone that,

00:33:10.425 --> 00:33:16.455
um, Being thoughtful and mindful
of the way that our messages are,

00:33:18.535 --> 00:33:23.449
you know, that has an impact
that essentially can last longer
than your tenure at the company.

00:33:23.780 --> 00:33:25.250
<c.speaker>Charlie:</c> Um, yeah, yeah, totally.

00:33:25.250 --> 00:33:28.160
<c.speaker>Tim:</c> The git, the git history
is gonna be there for a while.

00:33:28.850 --> 00:33:29.420
. Um...

00:33:29.840 --> 00:33:30.100
<c.speaker>Charlie:</c> Ya.

00:33:30.660 --> 00:33:30.880
Ya.

00:33:32.100 --> 00:33:39.870
<c.speaker>Tim:</c> So the machine learning company
that you were at, you wrote a blog
post in 2022 talking about mypy.

00:33:40.110 --> 00:33:40.680
<c.speaker>Charlie:</c> Oh, yeah.

00:33:40.680 --> 00:33:40.740
Yeah.

00:33:41.940 --> 00:33:44.700
<c.speaker>Tim:</c> And uh, and static typing.

00:33:44.965 --> 00:33:47.845
So this is obviously, so we're sort
of several years down the track.

00:33:47.845 --> 00:33:56.845
So you started interning, I guess,
2015, um, by, by 2022, you had become
a senior engineer with a lot of,

00:33:57.965 --> 00:34:05.075
with sort of incubated, let's say
within, uh, this context of lots
of very significant role models.

00:34:05.235 --> 00:34:14.920
And now you, you are building, uh, a very
important product and you really want
to make sure that your code is robust.

00:34:15.060 --> 00:34:18.210
And so what was your main
message in that blog post?

00:34:18.250 --> 00:34:24.980
<c.speaker>Charlie:</c> Um, so yeah, so that originated,
yeah, after Khan Academy, I worked
at a company called Spring Discovery.

00:34:25.040 --> 00:34:30.010
Um, so drug discovery and diagnostics
company, um, all based on computer vision.

00:34:30.010 --> 00:34:36.190
So we were like taking very high
resolution pictures of cells and
then trying to train, um, models on

00:34:36.190 --> 00:34:43.630
them to understand what happens when
you introduce drugs or add viruses
or whatnot um, and in that context I

00:34:43.630 --> 00:34:48.389
was maintaining a lot of our software
infrastructure machine learning
infrastructure data infrastructure.

00:34:48.389 --> 00:34:55.025
So we just had Um, a lot of Python, uh,
because we were doing scientific computing
and so all our infrastructure was also

00:34:55.025 --> 00:35:01.314
Python, um, and we were a pretty small,
like, core engineering team, like, uh,
you know, like the, let's say the company

00:35:01.315 --> 00:35:07.495
as a whole was like 25 to 30, the sort
of, um, computational team, which was

00:35:07.505 --> 00:35:10.334
like software engineering, data science,
machine learning, was like eight.

00:35:10.885 --> 00:35:15.755
And like two of us were basically
responsible purely for infrastructure
and the rest were in some, were either

00:35:15.755 --> 00:35:19.785
like machine learning researchers who
were writing, who were building some
of their own infrastructure, but,

00:35:20.235 --> 00:35:22.675
uh, they were either machine learning
researchers or data scientists, right?

00:35:22.675 --> 00:35:27.615
Whose questions were to, uh, leverage data
to make discoveries and answer questions.

00:35:27.635 --> 00:35:28.519
So we were.

00:35:28.610 --> 00:35:33.020
We were building a lot of infrastructure
for them and we were building
infrastructure for, um, like the wet

00:35:33.020 --> 00:35:36.320
lab scientists who would then look at
all the data that we generated and, and

00:35:36.320 --> 00:35:40.689
again, try to answer questions like which
drugs are most promising on X or Y axes.

00:35:41.290 --> 00:35:49.010
Um, so we were a small team trying to
do a lot and like the main way that we
got a big lift was, was tooling, right?

00:35:49.019 --> 00:35:51.720
It was like static typing
was like a big part of it.

00:35:51.720 --> 00:35:57.569
We had, um, at least by my standards,
a pretty large and extremely
heavily typed code base, and that

00:35:57.599 --> 00:36:01.865
enabled us to to, um, I mean, Python
typing, we talk about it a lot.

00:36:01.875 --> 00:36:03.305
There's like a lot of opinions on it.

00:36:03.345 --> 00:36:06.165
Um, at least in that context,
it, it enabled us to do a lot of

00:36:06.165 --> 00:36:08.815
refactors that otherwise would
have been completely impossible.

00:36:08.845 --> 00:36:14.205
<c.speaker>Tim:</c> So you made the claim, I don't,
not so much the claim, but that you.

00:36:14.540 --> 00:36:24.809
had probably the most strict, you set
MyPy to be as difficult as possible
for your developers for a code base

00:36:24.810 --> 00:36:28.060
that was roughly 300, 000 lines
of code, give or take, let's say.

00:36:28.420 --> 00:36:32.939
And so that's a significant amount of
code maintained by a pretty small team.

00:36:33.319 --> 00:36:40.939
And you decided to run, do Python,
let's say on hard mode and you
would disallow any, for example,

00:36:42.029 --> 00:36:43.750
<c.speaker>Charlie:</c> Yeah, yeah, yeah.

00:36:43.750 --> 00:36:46.870
So like the any type,
yeah, we didn't allow that.

00:36:47.000 --> 00:36:54.229
Um, uh, and it's, it's very hard to, yeah,
it's, I, who knows if that claim is true.

00:36:54.229 --> 00:36:56.879
It's probably not, but like we
had a very, we had basically, we

00:36:56.880 --> 00:36:59.929
had a very large Python code base
that was extremely strictly typed.

00:37:00.029 --> 00:37:07.609
Um, and, uh, you know, that blog post
really was about the, it's sort of a
common theme with some of the Python

00:37:07.609 --> 00:37:12.910
tooling, which is that, and it's one
of the reasons really, probably the
primary motivation for starting to

00:37:12.910 --> 00:37:19.040
work on ruff was that, um, the tooling
just really struggled to scale with
the systems that we were building.

00:37:19.739 --> 00:37:27.205
Um, and in ruff, you know, I think ruff
has since actually grown to ... have
a lot of other value propositions that

00:37:27.205 --> 00:37:30.885
aren't just performance, some of which
were intentional, some were unintentional.

00:37:31.185 --> 00:37:35.345
Um, but, uh, but performance was really
like the big one that we started with.

00:37:35.704 --> 00:37:40.054
Um, the unintentional, I think you're
reacting to this idea of like, some

00:37:40.055 --> 00:37:44.225
of them are unintentional, like,
rough bundles a lot of tools together.

00:37:44.275 --> 00:37:51.760
So like sometimes when we see people adopt
rough, they might replace like 20 or 30
dependencies, like individual tools, um,

00:37:51.810 --> 00:37:58.779
because in Python, um, the, the tooling
landscape is, is very fragmented, um, I
guess fragmented is kind of pejorative.

00:37:58.899 --> 00:38:05.109
Um, there are lots of different tools that
people kind of compose together to get
to their end user, their end experience.

00:38:05.379 --> 00:38:06.910
You know, there are different linters.

00:38:06.910 --> 00:38:08.080
The linters have lots of plugins.

00:38:08.379 --> 00:38:10.100
Import sorting is a separate tool.

00:38:10.120 --> 00:38:11.669
Code formatting is a separate tool.

00:38:11.700 --> 00:38:13.169
Type checking is a separate tool.

00:38:13.629 --> 00:38:16.600
There are separate tools for
like modernizing your code.

00:38:16.779 --> 00:38:20.180
Um, there's just like a lot of different
tools that people tend to chain together.

00:38:20.660 --> 00:38:21.970
And in Ruff, we ended up.

00:38:22.359 --> 00:38:23.979
Basically bundling all
that stuff together.

00:38:23.979 --> 00:38:28.870
So it's like one tool that you
download and install and learn and
exposes all those capabilities.

00:38:29.509 --> 00:38:34.819
And that was sort of an unintentional
thing because it was very
hard to build a plugin system.

00:38:36.129 --> 00:38:40.359
Like early on, I was like, I
don't really know like how to
build a plugin system here.

00:38:40.430 --> 00:38:45.209
It's just like, there are, it's actually
a pretty interesting design space of
like, how can you build a plugin system?

00:38:45.570 --> 00:38:46.960
For a tool that's written in Rust.

00:38:46.980 --> 00:38:50.490
And there are actually a lot
of interesting options there
and we may do it eventually.

00:38:50.770 --> 00:38:52.570
But early on, I was like, I
don't really know how to do this.

00:38:52.570 --> 00:38:55.640
So like, but this project wants to use
my tool and they need this functionality.

00:38:55.640 --> 00:38:57.120
So I'm just going to
build it into the tool.

00:38:57.440 --> 00:39:00.520
And like, we ended up, we kind of ended up
bundling a lot of this stuff by accident.

00:39:00.659 --> 00:39:03.809
It became a very big part of the
value proposition because especially

00:39:03.809 --> 00:39:05.980
for small projects, maybe they
don't care at all about performance.

00:39:06.475 --> 00:39:10.875
But like the idea of being able to greatly
simplify their toolchain is really useful.

00:39:11.395 --> 00:39:16.075
So, um, that was something that
was a little bit unintentional, but
has become a big part of what we're

00:39:16.075 --> 00:39:21.685
trying to do, which is like a lot
of, we want to simplify a lot of the
tooling by bundling things together.

00:39:22.065 --> 00:39:27.485
Um, and it's similar for packaging, like
packaging again, Um, for any one thing
you want to do in Python, there's like

00:39:27.505 --> 00:39:30.759
10 different tools you could use and you
might need like three or four of them.

00:39:30.759 --> 00:39:33.475
And you have to figure out like which
ones and you have to understand.

00:39:35.185 --> 00:39:39.005
We don't need to talk about Python
packaging, but it's, and again,
it's a similar thing where like we

00:39:39.005 --> 00:39:44.995
want to ship like UV, like right
now I would say it can comfortably
replace like three or four things.

00:39:45.145 --> 00:39:47.635
Like instead of three or four
separate things, you can just use UV.

00:39:47.964 --> 00:39:54.415
And like, we want to like expand the scope
of the number of things it can do so that
it's more of a self contained experience.

00:39:54.734 --> 00:40:01.874
Um, but that was a funny thing to realize
over time was, um, we started from this

00:40:01.884 --> 00:40:05.725
position of it's hard to build plugins, so
let's just implement everything ourselves.

00:40:06.204 --> 00:40:07.734
Um, and that turned into a feature.

00:40:08.394 --> 00:40:17.804
<c.speaker>Tim:</c> So how do you introduce
a tool to an ecosystem without
coming across as trying to invade.

00:40:19.265 --> 00:40:20.904
<c.speaker>Charlie:</c> Yeah, that's
a really good question.

00:40:20.935 --> 00:40:27.055
And actually something I've been,
I've been very grateful or like, I
don't know, I feel lucky, I guess.

00:40:27.095 --> 00:40:32.125
Like the Python ecosystem in general has
been very welcoming to, like, our work

00:40:32.125 --> 00:40:35.345
and the stuff that we're building and it
definitely didn't have to be that way.

00:40:35.415 --> 00:40:41.415
Like I could also see a world where
people were, really, there was a lot more
pushback and people were a lot more upset.

00:40:42.665 --> 00:40:47.705
And in particular for me because
like I haven't really been like
part of the Python ecosystem.

00:40:48.645 --> 00:40:52.480
Like I've been average
Python consumer, right?

00:40:52.480 --> 00:40:56.770
I was like writing a lot of
Python code, but like, I'm not
reading the enhancement proposals.

00:40:56.830 --> 00:40:58.980
I'm not on the Python forum.

00:40:59.369 --> 00:41:03.450
Um, I'm not like a contributor
even to any like Python.

00:41:03.499 --> 00:41:04.820
This is before I started on ruff.

00:41:04.840 --> 00:41:07.079
Like I wasn't like contributing
to open source even, right.

00:41:07.079 --> 00:41:11.060
I was like average passive consumer
of open source and of Python.

00:41:11.300 --> 00:41:12.960
That is the vast majority of people.

00:41:13.200 --> 00:41:18.720
Yes, it is the vast majority of people,
um, which is something that I have
to kind of remind myself of over time

00:41:18.720 --> 00:41:23.880
because now I've, now I like know a
lot of people in the ecosystem and I'm
like way more plugged into what's going

00:41:23.880 --> 00:41:29.559
on and I'm a lot more of an expert
in the standards and, and things like
that and you have to, you have to like

00:41:29.909 --> 00:41:33.740
remind yourself that like most people
do not come from that, um, perspective.

00:41:33.740 --> 00:41:37.339
Like I wouldn't have known, I didn't
know the difference between like a built,
I didn't, I didn't know the difference

00:41:37.339 --> 00:41:42.450
between a built distribution and a
source distribution in Python, like
until I started working on that stuff.

00:41:42.730 --> 00:41:52.929
Um, so anyway, but, um, I, it's been
interesting to come into that ecosystem
as a little bit of an outsider, um, uh,

00:41:53.449 --> 00:41:57.600
uh, you know, someone who I didn't really
know, like many of the people or whatnot.

00:41:58.319 --> 00:42:01.049
Um, you know, I think a
few things that we've.

00:42:01.290 --> 00:42:09.150
We've also tried to do, um, One, um,
We've tried to build things that are,

00:42:09.150 --> 00:42:14.670
like, relatively composable and that you
can use, um, in sort of a piecemeal way.

00:42:14.730 --> 00:42:17.400
Like, they come together in a
holistic, as a holistic tool.

00:42:17.589 --> 00:42:20.210
But, like, in ruff, we have, like,
for example, a linter and a formatter.

00:42:20.620 --> 00:42:23.640
And, like, there's a lot, you can use
just the linter or just the formatter.

00:42:23.660 --> 00:42:25.980
And there's a lot of people who
use ruff as just a linter or a

00:42:25.980 --> 00:42:29.880
formatter and then they, um, they
use some, they use black, right?

00:42:29.930 --> 00:42:33.100
Or they use a different, or
they use pylint alongside ruff.

00:42:33.410 --> 00:42:40.940
And so part of it has been like
trying to make clear and also be
part of an ecosystem where like,

00:42:40.950 --> 00:42:43.509
we're not necessarily trying to
like cannibalize those tools.

00:42:43.509 --> 00:42:51.370
Like we spend a lot of time interacting
with the people who work on black and
we talk a lot about preview style and

00:42:51.370 --> 00:42:54.650
like what style changes should we make
and like sometimes we report bugs.

00:42:54.660 --> 00:42:56.310
Sometimes we fix bugs right in black.

00:42:56.340 --> 00:43:02.869
Um, Similar for pylint like a lot
of people use pylint with ruff and
so we have a good relationship.

00:43:02.889 --> 00:43:06.749
You know we sponsor someone who works
on pylint and like we have a good
relationship with the tool and like

00:43:07.039 --> 00:43:10.720
That's helpful for both tools because
we can build a better experience.

00:43:11.850 --> 00:43:16.935
So, you know part of it is like Uh,
and again, it's similar with UV and
like with Pip, like we've talked with

00:43:16.935 --> 00:43:20.425
the Pip people a lot and like the
projects have pretty different goals.

00:43:20.425 --> 00:43:24.285
And I think it's great that there could
be multiple viable installers in Python

00:43:24.285 --> 00:43:27.385
and that the standards and the specs
evolve enough to make that possible.

00:43:27.855 --> 00:43:34.915
Um, and so, uh, you know, I think,
I think part of it is like, I don't
really view it necessarily as zero sum.

00:43:35.400 --> 00:43:40.790
And, um, I, I see us more as
like part of an ecosystem of

00:43:40.790 --> 00:43:43.730
tools and, you know, obviously I
want us to build the best thing.

00:43:43.740 --> 00:43:48.029
Like, otherwise, I don't know
why work on something if you
don't want it to be great.

00:43:48.180 --> 00:43:52.089
But like, but, um, you know, I
also recognize that like all those

00:43:52.089 --> 00:43:55.180
tools are used by like, also used
by like millions of projects.

00:43:55.240 --> 00:43:57.990
And, um, a lot of people who use
our stuff also use that stuff.

00:43:57.990 --> 00:43:58.230
Right.

00:43:58.230 --> 00:44:00.440
And like, I want to make
Python as a whole better.

00:44:00.810 --> 00:44:04.784
So I don't know, that's some of how
I think about this, but, um, yeah.

00:44:06.154 --> 00:44:13.234
You know, I think I think part of
it too is just like Be like just
genuinely just like being a nice person.

00:44:13.395 --> 00:44:13.855
I guess.

00:44:13.875 --> 00:44:17.245
I don't know like I Think like I just I'd

00:44:17.274 --> 00:44:18.144
<c.speaker>Tim:</c> Right, right.

00:44:18.165 --> 00:44:21.914
Come in there and say,
"Hey, you need to use this.

00:44:22.215 --> 00:44:22.945
You're all wrong."

00:44:23.165 --> 00:44:28.745
<c.speaker>Charlie:</c> Yeah, no, I I just try and
like, you know, I hope we build great
things and I try to just let them like

00:44:28.745 --> 00:44:36.835
speak for themselves and obviously I add
try and advertise our work in various
places, but I Try pretty hard not to

00:44:36.835 --> 00:44:41.984
make it about Highlighting flaws and
other tools and try to make it a lot
more about highlighting the things that

00:44:41.984 --> 00:44:47.319
we do And, um, overall I've been, I've
been really happy with that and I'm happy

00:44:47.319 --> 00:44:50.020
with the collaboration that we're able
to have with people in the ecosystem.

00:44:50.190 --> 00:44:50.860
<c.speaker>Tim:</c> Fantastic.

00:44:51.170 --> 00:44:57.299
Do you want to, I noticed that, oh,
sorry, uh, uh, I allowed us to slip
away from one of the questions.

00:44:57.609 --> 00:44:58.910
<c.speaker>Charlie:</c> Can we go back to the VC?

00:44:58.940 --> 00:45:00.640
Can we go back to
talking about VC Venture?

00:45:00.709 --> 00:45:00.999
Yeah.

00:45:01.009 --> 00:45:01.470
Yeah.

00:45:01.600 --> 00:45:01.750
Okay.

00:45:01.750 --> 00:45:02.210
<c.speaker>Tim:</c> Yeah.

00:45:02.319 --> 00:45:02.799
Yeah.

00:45:03.130 --> 00:45:03.700
That's right.

00:45:03.720 --> 00:45:05.700
And it's like, Yeah.

00:45:05.700 --> 00:45:10.230
I'm, I don't want to push on
this, but it's something that
I'm kind of curious about.

00:45:10.370 --> 00:45:10.980
<c.speaker>Charlie:</c> I was going to bring it.

00:45:11.029 --> 00:45:11.990
I was going to bring it back up.

00:45:12.029 --> 00:45:12.190
Yeah.

00:45:12.190 --> 00:45:12.999
But I wasn't sure when.

00:45:14.339 --> 00:45:14.639
<c.speaker>Tim:</c> Yeah.

00:45:14.680 --> 00:45:14.950
Yeah.

00:45:15.040 --> 00:45:15.629
No, no, no.

00:45:15.669 --> 00:45:17.680
Now let's, um, let's,
let's, let's go there.

00:45:17.879 --> 00:45:18.269
<c.speaker>Charlie:</c> Yeah.

00:45:18.290 --> 00:45:25.629
So I think like part of it, you
know, for me early on when I decided
to like start a company and raise

00:45:25.629 --> 00:45:30.584
money around it, um, I just knew, I
guess there were a few, like, Yeah.

00:45:32.605 --> 00:45:35.605
You know, I didn't necessarily have like
a huge master plan written out in my head.

00:45:35.655 --> 00:45:42.205
Um, the things that I knew were
like, If we raise money, I would
know how to use it effectively.

00:45:42.955 --> 00:45:47.124
Um, as in, there was a lot, there was just
like a huge amount of stuff for us to do.

00:45:47.425 --> 00:45:52.085
And the early adoption of the
tooling had demonstrated to me
that people really wanted it.

00:45:52.415 --> 00:45:57.115
Like, we were like this, You know,
we had projects like SciPy, right?

00:45:57.115 --> 00:46:02.475
And like, like really like long
tenured projects were adopting a
tool that was very much like alpha.

00:46:02.715 --> 00:46:06.514
And so I was like, there is a, there is
a strong desire for this kind of tooling.

00:46:06.514 --> 00:46:12.265
Like I know that we can, um, build
great, hopefully great stuff that
people will really want to use.

00:46:12.265 --> 00:46:19.425
Um, and you know, I knew that if I was
going to keep working on it full time,
or sorry, if I was going to keep working

00:46:19.425 --> 00:46:22.095
on this tool and achieve the goals
of the tool, it had to be full time.

00:46:22.095 --> 00:46:25.104
Um, Like, it was just too
much work for it not to be.

00:46:25.105 --> 00:46:35.144
Um, and, uh, you know, and further, I had
this idea in my head for, like, things we
could do if we built this tooling, right?

00:46:35.144 --> 00:46:39.765
And this is where it comes back to,
like, building a business, is like,
if we build this, you know, this

00:46:39.765 --> 00:46:43.584
great tool chain, like, and what kind
of positioning does that give us to

00:46:43.595 --> 00:46:46.584
build and sell commercial services
that integrate with it really well?

00:46:47.065 --> 00:46:53.365
Um, and, you know, when you start a, a
company, especially a venture, again,
you don't have to necessarily have

00:46:53.365 --> 00:46:57.555
everything figured out, but you do have
to have a vision for what you're trying
to, what you're trying to achieve.

00:46:57.555 --> 00:47:01.505
And for us, it was like, uh,
and is, we want to build, um,

00:47:01.555 --> 00:47:04.865
you know, this high performance
unified Python tool chain in Rust.

00:47:05.210 --> 00:47:09.760
And then we want to use that, um,
uh, that to sell you kind of like

00:47:09.760 --> 00:47:11.970
the natural next thing you need
when you're working with Python.

00:47:11.970 --> 00:47:13.919
So it could be all sorts
of different things, right?

00:47:13.920 --> 00:47:18.630
Could be like package hosting and
registries could be CI CD integrations
could be deployment and hosting.

00:47:18.630 --> 00:47:23.469
Like I just saw all these opportunities
where if we built this really amazing
tooling layer, then for people who

00:47:23.469 --> 00:47:27.760
are already using our tooling, there's
a lot of problems we could solve by
integrating with that tooling and

00:47:27.760 --> 00:47:33.029
integrating across them, like, okay,
we're your linter and your package
manager and all these different things.

00:47:33.639 --> 00:47:39.040
Um, You know, I think for me,
like the way I view it is, um, we,

00:47:41.710 --> 00:47:44.990
like we want to build all this great
tooling and that requires investment.

00:47:45.010 --> 00:47:47.280
And so we need to build a
sustainable business around it.

00:47:48.000 --> 00:47:52.250
I think a couple, one interesting thing
about this company, which is a little
bit different than a lot of other open

00:47:52.250 --> 00:47:58.940
source companies for better or for worse
is like the traditional business model for
venture-backed companies in open source

00:47:58.980 --> 00:48:05.779
is you often build, uh, you have some
sort of thing that needs to be hosted and
then you charge people, you then you host

00:48:05.780 --> 00:48:11.060
it and people pay you money for that and
then you sell other enterprise services
on other enterprise features on top of it.

00:48:11.480 --> 00:48:13.190
We actually like don't fit that model.

00:48:13.540 --> 00:48:20.620
Um, uh, it's not like, I mean, I think
you could imagine like what a hosted
ruff is like, I could probably like,

00:48:21.030 --> 00:48:26.650
you know, I could sketch something out,
but it doesn't, it's not really like
what people are doing with the tooling.

00:48:26.929 --> 00:48:29.359
Um, you know, it's not like we
have a piece of database software

00:48:29.359 --> 00:48:31.720
and then we're going to host the
database for you and sell the hosting.

00:48:32.180 --> 00:48:36.230
So, um, I actually think, I
mean, it's good and it's bad.

00:48:36.460 --> 00:48:39.250
It's bad because there are fewer
companies that I could point to.

00:48:39.280 --> 00:48:41.710
I can point to some, but there are fewer
companies I can point to that follow.

00:48:42.320 --> 00:48:43.550
What we were trying to do.

00:48:44.210 --> 00:48:49.120
But I think it's, I think it's good
because it means that at least from
my perspective, I think we're really

00:48:49.130 --> 00:48:52.430
incentivized to like build out the
open source in a very holistic way.

00:48:52.669 --> 00:49:00.240
Um, and, uh, you know, we're not
like, we don't suffer from a lot of
the same licensing issues, I guess,

00:49:00.250 --> 00:49:04.130
that people follow in that model where
you're a little bit disincentivized.

00:49:04.750 --> 00:49:08.170
I guess I don't want to like talk bad
about any of those companies, but it's
like, sometimes you're kind of distant.

00:49:08.430 --> 00:49:09.930
The incentive alignment is not perfect.

00:49:10.310 --> 00:49:12.400
I think it's the alignment of incentives
and that's why they're very imperfect.

00:49:13.720 --> 00:49:17.770
And for us, I want to have
the incentive structure such
that we build the open source.

00:49:17.810 --> 00:49:19.750
Our goal is for it to
grow as much as possible.

00:49:19.970 --> 00:49:24.380
Um, you know, ideally, you know,
if I, put on my CEO hat, ideally it

00:49:24.380 --> 00:49:28.320
becomes, um, you know, a funnel for
you, for paying customers, right?

00:49:28.320 --> 00:49:29.810
So we know all these
people are using our stuff.

00:49:30.120 --> 00:49:32.540
We build and sell services that
integrate with it really well.

00:49:32.590 --> 00:49:35.190
And then our incentive structure is
continue to build out the open source.

00:49:35.199 --> 00:49:36.590
Ideally make it really popular.

00:49:36.779 --> 00:49:38.690
Ideally make it something
that companies can use.

00:49:38.899 --> 00:49:44.650
Um, and then use that as a mechanism
to attract customers and people
who will pay for our stuff.

00:49:45.010 --> 00:49:47.670
Um, so that's, that's the incentive.

00:49:47.710 --> 00:49:51.969
I care a lot about like the incentive
structure and like that is the
incentive structure I want to have.

00:49:52.865 --> 00:49:59.875
I do think, um, I think there's like some,
you know, some like challenges around,

00:49:59.985 --> 00:50:04.515
um, they're not really that different
from other open source projects, I guess.

00:50:04.515 --> 00:50:08.525
But like, you know, we have
a team of nine people who are
working full time on this stuff.

00:50:08.655 --> 00:50:16.950
Um, and we also want it to be a
project that has, um, Ideally, I would

00:50:16.950 --> 00:50:19.590
like to get our products to a point
such that they outlive the company.

00:50:19.750 --> 00:50:22.210
Like that is not true today, for sure.

00:50:22.600 --> 00:50:26.040
Um, like we don't have,
we have no one on who...

00:50:26.070 --> 00:50:28.539
We have no one with commit access
to the project that doesn't work

00:50:28.540 --> 00:50:31.970
at the company, for example, and
like a healthy, sustainable...

00:50:32.469 --> 00:50:34.420
<c.speaker>Tim:</c> May I raise a hypothetical?

00:50:34.420 --> 00:50:42.860
Which is, let's say, the Python Software
Foundation says, look, ruff is now so

00:50:43.100 --> 00:50:48.850
important that we're going to, to ... We'd
like you to assign copyright to us.

00:50:49.430 --> 00:50:53.380
Uh, and essentially the funding model
is all, is kind of the same, but

00:50:53.380 --> 00:51:00.020
you are now the primary, ... We're
the owners of the software.

00:51:00.710 --> 00:51:07.999
We have in some sense control,
but you, your team now has
the most knowledge of it.

00:51:08.030 --> 00:51:09.139
Does that make any sense?

00:51:09.660 --> 00:51:16.400
<c.speaker>Charlie:</c> Um, like do I understand the
situation or is this, or do I think, do I
agree that that would be a good outcome?

00:51:17.360 --> 00:51:19.619
<c.speaker>Tim:</c> No, no, no, no, no, no, no.

00:51:19.619 --> 00:51:23.660
Like, no, I don't even know if there
is a question there, but it'd be

00:51:23.680 --> 00:51:29.440
interesting to hear how the software
project could outlive the company.

00:51:29.760 --> 00:51:37.145
Presumably that would mean giving it to
some other shepherd to kind of, you know,
Or something else to kind of maintain.

00:51:37.485 --> 00:51:37.905
<c.speaker>Charlie:</c> Yeah.

00:51:37.945 --> 00:51:38.395
Yeah.

00:51:38.535 --> 00:51:42.755
I think there are like some other
projects that have done a really good job
of this that I look to as role models.

00:51:42.755 --> 00:51:51.704
Like one is, um, confusingly similarly
named, but Astro A S T R O in the
web and the JavaSc[ript], in the web

00:51:51.704 --> 00:51:58.045
ecosystem, let's say, um, like they
just have a really good governance
structure in my opinion, at least.

00:51:58.115 --> 00:52:05.405
Um, and you know, for example, Uh, you
know, there, there are roles, there's
like a sort of a hierarchy of roles,

00:52:05.545 --> 00:52:11.255
and when you join the Astro Technology
Company, you're just like slotted in
somewhere in that hierarchy, and like

00:52:11.275 --> 00:52:16.114
people who don't work at the company could
be above you, or you know, or below you,
based on the contributions that they've

00:52:16.114 --> 00:52:21.135
made in open source, um, and there are
like sort of clear guidelines for how
you move up or down in that hierarchy,

00:52:21.495 --> 00:52:25.585
um, and, and, you know, and they have
like, they have an OpenCollective.

00:52:25.755 --> 00:52:30.345
So like they have like, they
have corporate sponsors and other
people can donate to the project.

00:52:30.565 --> 00:52:35.744
And then those funds are used to
support, oh, they, those funds cannot
go to employees of the Astro company.

00:52:35.745 --> 00:52:41.664
They're used to support open source
contributors, um, uh, you know, events
for the project, et cetera, et cetera.

00:52:41.665 --> 00:52:44.715
So they just, in my opinion, at
least like they've thought about

00:52:44.715 --> 00:52:47.815
it a lot and put a lot, it's
very hard to do that effectively.

00:52:47.825 --> 00:52:50.655
It takes like a ton of work,
especially when you're doing
like a million other things.

00:52:50.970 --> 00:52:55.540
Um, but, so I have a lot of respect
for it and like, that's kind of
what I want to build to over time.

00:52:55.970 --> 00:52:59.480
Um, but, but we're certainly,
we're definitely not there yet.

00:53:00.340 --> 00:53:08.290
<c.speaker>Tim:</c> Now I want to respect your time,
but also I want to see if I can suck
out some of, uh, your knowledge.

00:53:08.340 --> 00:53:19.350
And there's one sort of final kind of
question that I've got, which is, Was
there a part of developing Ruff that you

00:53:20.325 --> 00:53:25.515
really relished in from like a technology
or data structure kind of problem.

00:53:26.055 --> 00:53:30.725
Um, was it, you know, if you were
to like think, well, actually that
was, you know, when you started out,

00:53:30.735 --> 00:53:34.224
it was really fun and interesting
kind of intellectually engaging.

00:53:35.294 --> 00:53:38.125
Uh, what was that like?

00:53:38.204 --> 00:53:40.095
And, and, and could you explain that?

00:53:40.635 --> 00:53:41.395
<c.speaker>Charlie:</c> Yeah, totally.

00:53:41.395 --> 00:53:46.365
I mean, I think like for
me, I'd never really built
anything like a linter before.

00:53:46.495 --> 00:53:49.705
Um, and so.

00:53:51.130 --> 00:53:57.260
Like a lot of the initial
infrastructure around like semantic
analysis was really interesting.

00:53:57.270 --> 00:54:02.500
So, um, you know, when, when I first
shipped and the first ruff release

00:54:02.730 --> 00:54:06.399
supported a pretty small number of
rules, but I wanted to make sure...

00:54:06.410 --> 00:54:07.900
It was really a proof of concept.

00:54:08.230 --> 00:54:11.240
But I wanted to make sure that it could
support some fairly sophisticated rules.

00:54:11.250 --> 00:54:13.680
So, like, unused import
detection, for example.

00:54:14.030 --> 00:54:21.620
That requires like, um, a fair amount
of semantic analysis, like, you need to
be able to identify, basically, you need

00:54:21.620 --> 00:54:25.890
to be able to identify which imports are
used and which are not, so you need to
be able to resolve references, you need

00:54:25.900 --> 00:54:29.460
to be able to deal with, like, shadowing,
like someone imports something and then

00:54:29.890 --> 00:54:32.839
assigns to a variable with the same name,
and then that variable is used, right?

00:54:32.840 --> 00:54:37.849
I mean, it's like, basic stuff when,
from the perspective of the programmer,
but from a perspective of program

00:54:37.850 --> 00:54:44.300
analysis, as in the Python, the end
Python programmer understands a lot of
those rules and understands whether an

00:54:44.300 --> 00:54:47.580
import's used or not, but like, from
the perspective of program analysis,

00:54:47.590 --> 00:54:50.170
it just required a lot of things I
had never really seen or done before.

00:54:50.480 --> 00:54:57.240
Um, uh, a lot of that stuff I
learned by reading other codebases.

00:54:57.860 --> 00:55:04.850
Like, open source is pretty amazing
because you can just go look at
how people solve certain problems.

00:55:05.079 --> 00:55:11.610
Um, and, and so like the PyFlakes
codebase, which was the, uh, um, uh,

00:55:11.620 --> 00:55:15.180
where we, a lot of the rules that they
have are rules that we then implemented.

00:55:15.400 --> 00:55:18.990
Like, I read that really thoroughly
in trying to understand, like,
how do they deal with bindings?

00:55:19.020 --> 00:55:20.929
What are the different
representations that they used?

00:55:20.960 --> 00:55:26.000
And, like, that model has evolved
substantially over time, especially as
I've brought people into the team who

00:55:26.000 --> 00:55:31.050
are, like, have a lot more experience
than me at those kinds of problems, and,
like, we've evolved that semantic model.

00:55:31.370 --> 00:55:36.190
Um, but that was a really cool
thing, like, being able to do
program analysis in that way.

00:55:36.560 --> 00:55:42.205
Um, I also, maybe another thing
that was really rewarding for
me in a slightly different way.

00:55:42.775 --> 00:55:43.305
Um.

00:55:44.075 --> 00:55:44.745
We...

00:55:45.475 --> 00:55:54.124
when we started working on the formatter,
um, it's a very interesting set of
problems, um, around code formatting

00:55:54.214 --> 00:56:01.840
and, um, uh, one of the first two people
that I hired, uh, his name is Mika,
And he worked on, um, he'd worked on

00:56:01.840 --> 00:56:07.739
a Rust-based formatter for JavaScript
before and he brought in a lot of
knowledge around, kind of like, the right

00:56:07.739 --> 00:56:12.040
way to do that, um, and adapting it to
Python and some of the quirks of Python.

00:56:12.300 --> 00:56:19.160
And so, like, working on that and
seeing, um, some of the things he did for
performance, some of the things that were

00:56:19.160 --> 00:56:23.895
just, like, hard problems to solve, like
comment association, is like so hard.

00:56:24.135 --> 00:56:26.935
Um, like how do you, like, yeah.

00:56:26.935 --> 00:56:32.655
I would say like 75 percent of the
challenge of the formatter is comments.

00:56:33.425 --> 00:56:37.455
Like the basic code formatting
is not, I mean, it is hard.

00:56:38.444 --> 00:56:43.155
Um, but like comments are like
so much of the complexity.

00:56:43.730 --> 00:56:46.260
Because, anyway, it's not
necessarily interesting, but

00:56:46.260 --> 00:56:46.930
<c.speaker>Tim:</c> Where should you put them?

00:56:46.970 --> 00:56:47.710
<c.speaker>Charlie:</c> Yeah, where do you put them?

00:56:47.910 --> 00:56:49.540
Um, and they can go basically anywhere.

00:56:49.740 --> 00:56:53.780
Um, and so the chain formatting,
you can put comments between
basically any two tokens.

00:56:53.849 --> 00:56:56.309
So like, not quite, but like almost.

00:56:56.340 --> 00:57:00.299
Um, so it just creates like
a real explosion of cases
that you need to handle.

00:57:00.320 --> 00:57:00.794
Um, yeah.

00:57:01.255 --> 00:57:03.165
But the basic rules of
like, how do you figure out?

00:57:03.205 --> 00:57:04.145
Is it a leading comment?

00:57:04.155 --> 00:57:05.255
Is it a trailing comment?

00:57:05.265 --> 00:57:07.035
What node should it be associated with?

00:57:07.035 --> 00:57:12.224
Is it part of the, you know, if you
have a comment on the first argument
of a function definition, is it

00:57:12.224 --> 00:57:15.595
part of like the function definition
or is it part of the argument?

00:57:15.634 --> 00:57:20.615
Um, you know, and there's just a lot
of, like, understanding the rules around
that was very, it was really interesting.

00:57:21.875 --> 00:57:23.995
It became painful over time,
but it was very interesting.

00:57:24.005 --> 00:57:24.415
<c.speaker>Tim:</c> Extremely.

00:57:24.875 --> 00:57:28.105
You snuck in something else
in there, which I thought was
really, really nice, which.

00:57:28.630 --> 00:57:34.350
Um, you know, essentially once you
decided to build a compiler company,

00:57:34.810 --> 00:57:43.310
you brought in experts and then you were
able to benefit from others' expertise.

00:57:43.340 --> 00:57:50.910
And I think one of the hard, or like
the big challenge when you move from
solo to a small team, and then as your

00:57:50.910 --> 00:57:56.185
team grows, is that you need, you start
hiring people that are better than you.

00:57:56.965 --> 00:57:57.105
<c.speaker>Charlie:</c> Yeah.

00:57:57.105 --> 00:57:57.715
That's good though.

00:57:59.575 --> 00:57:59.895
Yeah.

00:58:00.395 --> 00:58:03.215
<c.speaker>Tim:</c> And, uh, 100 percent it's good.

00:58:03.275 --> 00:58:08.614
And it just kind of reinforces that idea
of trust, which, um, which is extreme.

00:58:08.614 --> 00:58:08.984
<c.speaker>Charlie:</c> Yeah.

00:58:08.985 --> 00:58:18.655
I mean, well, maybe just last thing I'll
say really quick is like the biggest,
like starting a company, like it's, um,

00:58:20.185 --> 00:58:23.825
Sorry, the bigger evolution, the bigger
change in my life was not like starting

00:58:23.825 --> 00:58:27.255
a company, it was actually like hiring,
hiring employees and people to work there.

00:58:27.275 --> 00:58:32.725
Because like, when I started a
company, like, yes, I'm putting some
things on the line, but it's just me.

00:58:33.375 --> 00:58:37.690
And then when other people join,
like, Yeah, it just becomes, um, you

00:58:37.690 --> 00:58:41.000
know, suddenly the responsibility
like goes far beyond yourself.

00:58:41.380 --> 00:58:46.480
Um, and so that to me was the biggest
change was like bringing on other

00:58:46.480 --> 00:58:50.650
people on the team, and, you know now
having a responsibility to them as well.

00:58:50.989 --> 00:58:56.440
Um, so anyway, yeah, uh, it's it's it is
an amazing vote of confidence to, like...

00:58:57.860 --> 00:58:59.960
Have people come join
you on what you're doing.

00:59:00.230 --> 00:59:06.790
Um, and I think we've built, um,
a team that's like so much better
than I ever could have imagined.

00:59:06.800 --> 00:59:12.080
Like we've just tracked, we've just
been able to, um, hire some really
incredible people, but it's also,

00:59:12.310 --> 00:59:16.860
yeah, for anyone out there who's
considering starting a company, it is
also a lot of responsibility, right?

00:59:16.860 --> 00:59:21.989
It's other people's entire lives,
um, or sorry, or their livelihoods,
I guess would be the right word.

00:59:22.330 --> 00:59:29.249
Um, but yeah, anyway, so maybe, uh,
I don't know, a somber note to end
on or an energizing note, right?

00:59:29.419 --> 00:59:29.869
I don't know.

00:59:30.459 --> 00:59:41.350
<c.speaker>Tim:</c> Yeah, no, I think, like, it's,
it's, it's, it is an energizing, um,
note and it It is important to me that

00:59:41.530 --> 00:59:51.130
senior leaders at even small companies
are aware of the responsibility
that they have for the employees.

00:59:51.170 --> 00:59:55.900
I think that, um, Yeah, it
is people's livelihoods.

00:59:56.020 --> 01:00:01.360
And as, uh, as someone also at a
very similar, oh, you know, I'm

01:00:01.360 --> 01:00:04.750
actually at a much earlier stage
in my, my own business, really.

01:00:04.950 --> 01:00:10.969
Um, I can definitely empathize
with how, for me, it's sort of

01:00:11.020 --> 01:00:14.589
tight, slightly terrifying, this
idea of do we bring people on?

01:00:15.269 --> 01:00:25.060
Um, because You know, I've got X
months of, uh, let's say four to four
to six months of runway personally

01:00:25.060 --> 01:00:28.440
that I've been able to, you know, and
it's like, but what if that runs out?

01:00:28.560 --> 01:00:29.210
What happens then?

01:00:30.050 --> 01:00:30.610
Um,

01:00:30.680 --> 01:00:31.230
<c.speaker>Charlie:</c> Yeah.

01:00:31.330 --> 01:00:40.919
<c.speaker>Tim:</c> Anyway, I, um, I'm just, uh, so
thrilled that you're able to share
an hour or so with me today, Charlie.

01:00:41.299 --> 01:00:43.860
I am curious, how should
people connect with you?

01:00:43.910 --> 01:00:46.160
Um, follow Ruff, follow the company.

01:00:46.210 --> 01:00:46.410
<c.speaker>Charlie:</c> Yeah.

01:00:46.410 --> 01:00:49.060
The best of the best is on Twitter/X.

01:00:49.350 --> 01:00:51.060
Yeah, it's just @charliermarsh.

01:00:51.400 --> 01:00:54.440
Um, and that's where I'm,
that's where I'm most active.

01:00:54.590 --> 01:00:59.930
Um, and, uh, but otherwise on GitHub,
I mean, to the degree, it was not
quite, I don't know if I would

01:00:59.930 --> 01:01:02.869
describe GitHub as a social network,
but you can follow me on GitHub.

01:01:04.040 --> 01:01:07.254
Um, uh, but yeah, the
best, the best is on X.

01:01:08.055 --> 01:01:08.555
<c.speaker>Tim:</c> Superb.

01:01:08.705 --> 01:01:09.475
Okay, fantastic.

01:01:09.665 --> 01:01:10.375
Hey, thanks again.

01:01:10.465 --> 01:01:15.045
And, uh, I, uh, I'm going to be
watching you very intently online.

01:01:15.675 --> 01:01:19.525
<c.speaker>Charlie:</c> Yeah, thank you so much
for, um, uh, for having me on, for
reaching out, for setting this up.

01:01:19.525 --> 01:01:20.784
It was super fun for me too.

