Matthias: Here's another episode of Rust in Production, a podcast about companies who
Matthias: use Rust to shape the future of infrastructure.
Matthias: My name is Matthias Endler from corrode, and today we talk to Richard Feldman
Matthias: from ROC about their reasons for migrating from Rust to Zig.
Matthias: Richard, thanks so much for taking the time for the interview.
Matthias: Can you say a few words about yourself and about ROC, the programming language you're working on?
Richard: Yeah, sure. So I'm Richard. So my day job is I work at Zed Industries,
Richard: making the Zed code editor, which is all written in Rust.
Richard: So mostly what I spend my time on is writing Rust. On the side,
Richard: I have been developing for the past several years, the Roc programming language,
Richard: which I created, but I work on with a number of other people.
Richard: Originally, Roc's compiler was written in Rust completely. And now it's being
Richard: rewritten in Zig, which is what I assume we're going to talk about.
Matthias: Precisely. Yeah, it's perfect. we had said in
Matthias: a previous episode as well if you want to check that out we
Matthias: will link it in the show notes that was an amazing episode as
Matthias: well and also for this one i have
Matthias: really high hopes because your name was mentioned a couple times by a couple
Matthias: of our listeners because you wrote an article or maybe you published a post
Matthias: let's say about your migration from rust to Zig but before we get into that
Matthias: what is Roc what makes it special why did you start that project.
Richard: Yeah, so Roc's tagline is fast, friendly, functional.
Richard: And basically, it's a functional programming language. The goal is to be really, really fast.
Richard: We want it to be the fastest garbage collected language. That's sort of the goalpost that we set.
Richard: So I would say that Go right now, as far as I'm aware, is the fastest garbage collected language.
Richard: And we want to be faster than Go, not as fast as Rust or C++ or Zig or any of
Richard: those, because we want to be completely memory safe, guaranteed.
Richard: Speed and basically the the goal is to
Richard: be competing with languages like go or maybe like
Richard: you know ocamel also has a good reputation for speed while being
Richard: a functional programming language as opposed to like go being very imperative
Richard: so yeah that's that's the goal in terms of speed in terms of friendliness it's
Richard: like have really simple apis very very heavily inspired by elm Roc is sort
Richard: of an outgrowth of my really positive experiences with elm but elm is targeted
Richard: at compiling to JavaScript and front-end web development,
Richard: whereas Roc compiles to machine code or to WebAssembly and is sort of trying
Richard: to address all of these use cases that are not front-end web development.
Richard: Also, Roc's design has evolved quite a bit from Elm's. Now it's a much different
Richard: language. When it started out, it was very similar to Elm.
Richard: Now it's a lot less similar, but I think the essence of that sort of ethos of
Richard: simplicity and really nice APIs and really friendly compiler error messages and things like that.
Richard: Actually, Elm's error messages inspired Rust, even though So I think Rust is
Richard: now more famous for compiler errors.
Richard: So all of that is sort of what we're going for with Roc.
Matthias: And take us back to the time when you started the project.
Matthias: What was the ecosystem like? What were some of the other languages that you
Matthias: got inspired by when you started with Roc?
Matthias: And also, what was that initial spark that told you, hey, I need to do this,
Matthias: and now is the best time for it?
Richard: Really, the inspiration for it came from an experience I had.
Richard: This is back when I was working at NoRedInk. We had this huge Elm front end,
Richard: and we had Ruby on Rails for the back end. And Rails had been at the back end
Richard: for long before we started using Elm.
Richard: And we were trying to move the back end to something more functional.
Richard: And kind of what we discovered was that there was just really this missing piece
Richard: in the ecosystem, or at least that was my perception of it.
Richard: We ended up going with Haskell and trying to use Haskell in kind of an Elm-like way.
Richard: But my feeling was what we really want is a functional language that's statically
Richard: type checked with type inference built around purity. So OCaml is a functional
Richard: language, but it's really not like pure functions everywhere.
Richard: It's sort of like pure functions are encouraged, but they're not really first class in OCaml.
Richard: Same thing with F sharp. And basically what we ended up concluding was that it just doesn't exist.
Richard: Like there is no Elm equivalent outside of the browser.
Richard: And that was kind of the spark for me to go and do it.
Richard: As far as what languages inspired it, really it was Elm plus like maybe little
Richard: bits and pieces of other languages, but it's very primarily like,
Richard: okay, how do I take this great experience we've had with Elm and translate it
Richard: to other domains besides just the browser?
Richard: And I didn't want to just do servers. The kind of the idea was i'd be using
Richard: this phrase the long tail of domains like basically there's lots of different
Richard: use cases out there it's not just servers there's command line apps there's native graphical apps.
Richard: There's microcontrollers robotics you know there's this very long tail of different
Richard: things you can do with programming and i wanted to see could we bring an elm
Richard: like experience to all those different domains in terms of being a very simple
Richard: functional experience yeah.
Matthias: And i could see a few ways how this could go because the Rust compiler is not,
Matthias: or the first version of it wasn't written in Rust because Rust didn't exist, obviously.
Matthias: It was written on OCaml as well. And,
Matthias: Then you have Elm, which might be another way to implement a new language on
Matthias: top of, or maybe there's a language that I don't know of that you could use.
Matthias: But why did you choose Rust and which alternatives did you consider?
Richard: Yeah, also a great question. So basically, the reason I chose Rust was that
Richard: I wanted the compiler to be as fast as possible.
Richard: And I was, to be totally honest, scared of trying to do it in a memory unsafe
Richard: language based on past experiences I'd had with segmentation faults that I really
Richard: struggled to debug and stuff like that.
Richard: When I was very young, like middle school era, I got into C++ because I wanted to do game dev.
Richard: And I have some scars from trying
Richard: to do that and bumbling around and just making a huge mess for myself.
Richard: And the pitch of Rust of being, hey, you can have this really,
Richard: really high performance ceiling. In other words, there's no mandatory garbage collector.
Richard: There's no built-in boxing of things you
Richard: can be as fast as a c or c plus plus program but
Richard: you're going to have memory safety you don't have to worry about seg
Richard: faults and all these things that that you know i had these bad experiences with
Richard: in the past that was the pitch that sort of sold me because my thinking was
Richard: well if i do the compiler in oCaml or Haskell or something like that yeah that's
Richard: going to be a more familiar experience to me but at some point i'm going to
Richard: reach this point where i'm like i want it to go faster and i can't because i'm
Richard: limited by the performance ceiling of this language.
Richard: I don't want that and then at that point i'm like what am i going to do
Richard: i'm going to say oh now i rewrite it in rust you know this is something that's happening
Richard: in the javascript ecosystem a lot is that a lot of projects started off
Richard: being written in javascript because that's what was familiar to people and then
Richard: they realized past a certain point that a compiler is one of those use cases
Richard: where just more performance is better it's not like you get down to this point
Richard: you know in a lot of graphical applications it's kind of like well as long as
Richard: you're not dropping frames as long as you're under the you know however many
Richard: milliseconds you have within each frame Thank you.
Richard: Humans can't perceive a difference it's like it's fast enough and
Richard: if you make it faster nobody notices compilers are
Richard: not like that faster is pretty much always better it's
Richard: a it's just a big part of the ux is you know
Richard: how long are you waiting for rebuilds and stuff like that and so
Richard: my feeling was especially actually this this came
Richard: up in elm when we were using element NoRedInk at some point we
Richard: became the largest elm code base we had a couple hundred thousand lines
Richard: i don't remember exactly how big it was at the time but elm 0.18
Richard: we were really feeling the pain of compile
Richard: times it's like we'd had a really positive experience and it was becoming a
Richard: very negative experience just because we were waiting so long for rebuilds
Richard: and then when elm 0.19 came out evan had rewritten
Richard: a huge amount of the elm compiler which was written in haskell for
Richard: performance and it took him a long time it's months and
Richard: months and months but when it came out it was just this amazing
Richard: breath of fresh air all of our builds were fast again like they used to be when
Richard: our when our code base was small and that was a really important lesson for
Richard: me was yeah take the stuff seriously like compile times are a really big deal
Richard: and if you want to build a language that has a good end user experience you
Richard: know fast friendly functional part of that friendliness and user friendliness.
Richard: Is committing to having a compiler that is really really really fast and that's
Richard: something that i've been completely unwilling to compromise on since the beginning
Richard: of the project the compiler's always It's got to be really fast.
Matthias: Yeah. And that was in 2019. Correct me if I'm wrong here.
Matthias: What was your level of Rust experience when you started with implementing Roc?
Matthias: Was it your first big Rust project?
Richard: It was my first big Rust project. So previously in 2017, I had dabbled in Rust, I would say.
Richard: I'd written the Elm test runner originally in Node.js.
Richard: And it was honestly out of frustration with the Node.js ecosystem that I was
Richard: like, I just want to try something else. Why don't I try Rust?
Richard: I never actually shipped anything out of that project It was like I just started
Richard: rewriting it in Rust So I kind of got a feel for it And the experience that
Richard: I had initially with Rust Was positive enough that I was like Yeah, this...
Richard: This seems like something I'm willing to commit to for this compiler,
Richard: even though I know this is going to be a very, very long, you know,
Richard: project that I'm going to spend way more time on than this little sort of side
Richard: project thing that was just kind of for fun.
Richard: And I mean, my feeling going into this was that this is a language that I'm
Richard: planning on putting multiple decades of my life into.
Richard: And so committing to Rust with just that minimal level of experience was a bit
Richard: of a leaf of faith in the sense that I didn't have enough Rust experience to
Richard: know that I was going to like it that much long term.
Richard: But at the same time, I had enough experience.
Richard: It wasn't zero. It wasn't like I was sitting down and writing Hello World and Rust.
Richard: And then I was like, that's what this compiler is going to be in.
Richard: So I would say it was an informed decision, but my Rust experience at that point was pretty minimal.
Matthias: When you think in decades, how does it shape the decision-making process?
Richard: I would say the main thing is that it gives me the comfort to make long-term investments.
Richard: So a lot of projects that I've worked on in my career have been for startups.
Richard: And startups are often like, yep, in 18 months, we're going to be out of money
Richard: and disappeared off the face of the planet. So it's really important that we
Richard: survive the next 18 months.
Richard: And so making a long-term investment has to be balanced against,
Richard: okay, if we make this long-term investment, is that investment going to cause
Richard: us to not exist long enough to reap the benefits of the long-term investment?
Richard: And there's always that constant tension.
Richard: With this project, my feeling was the opposite. It's like, I'm very comfortable
Richard: making long-term investments.
Richard: The main thing I was actually thinking about was, and this is again,
Richard: shaped by my early experiences with Elm and participating in having the good
Richard: fortune to live in the same city as Evan Czaplicki who created Elm and being
Richard: able to talk to him about these things.
Richard: But basically understanding that if I'm going to be making a long-term investment in the language...
Richard: It's important that I also communicate that clearly and set expectations clearly
Richard: to people who are using the language.
Richard: So from the very beginning, I've tried really hard to communicate,
Richard: hey, things are not set in stone here. We're going to be making breaking changes
Richard: to this language, et cetera.
Richard: The strongest way that I've done that is we intentionally, even though,
Richard: like you said, the first line of code was 2019. I actually started designing it in 2018.
Richard: But ever since then, we still do not have a numbered release.
Richard: We're planning on having our first numbered release in 2026 like
Richard: 0.1.0 but the whole reason we've been doing that
Richard: is just to communicate you have to build from nightly expect things
Richard: to break despite this we still do actually have one
Richard: person who's been consistently using Roc in production at his job but that's
Richard: to me an appropriate level of cautiousness where like we only have one person
Richard: doing it even though lots of people have done Roc for hobby projects and stuff
Richard: because we are making big changes and so those are all things that i see as
Richard: long-term investments i think if i were thinking more short term,
Richard: I might be like, okay, no, we already need to be backwards compatible.
Richard: We can't, you know, new releases need to not break things.
Richard: Rust and Gleam and Go are all languages that I think went 1.0 and had a strong
Richard: backwards compatibility guarantee relatively early on. And I think that really
Richard: helped them with adoption.
Richard: But to me, my goal is not immediate term adoption. I'm more thinking about what
Richard: we're trying to do is really ambitious.
Richard: And I really, really, really want to get it right, or at least as close to right
Richard: as we can get it before we make commitments to backwards compatibility.
Richard: So that's the type of thing that I think thinking in decades has as a benefit.
Richard: It's that I can say, yeah, we've been working on this for years,
Richard: but we still don't have a numbered release because I really want to clearly
Richard: communicate to people, things are going to break.
Richard: Please don't expect that we're going to have backwards compatibility because
Richard: we're not ready for that yet.
Richard: But I think we're actually almost to the point where we are ready for that,
Richard: which is pretty exciting milestone to be coming up on hopefully next year.
Matthias: I want to talk about Rust, the
Matthias: good parts, for a moment, because not everything was bad, I'm assuming.
Matthias: In your post, you already mentioned a couple of really sane reasons to move away from Rust.
Matthias: But can you talk to us a little bit about the good parts, the things that you
Matthias: like about Rust, working with larger codebases, and what does it really feel
Matthias: like to work in the trenches with such a language?
Richard: Yeah, there are lots of good parts to Rust. And to be clear,
Richard: I like Rust overall as a language.
Richard: I'm not like a Rust hater. I'm not like, oh, Rust is old and busted and Zig
Richard: is like the new hotness. It's very much the opposite.
Richard: It's more that for this particular project, I ended up deciding that if we're
Richard: going to do a rewrite anyway, then that rewrite should be in Zig rather than
Richard: rewriting it again in Rust, which we'll get to. But yeah, Rust's the good part.
Richard: So I mean, the first thing that I would mention is that, like I said,
Richard: I work at Zed full time, and I don't think it would make any sense for Zed to move away from Rust.
Richard: Like Rust seems like it just fits the way that Zed's codebase works like a glove.
Richard: If you wanted to rewrite Zed in something other than Rust, first of all,
Richard: that sounds like a really daunting proposition, not just because it's a lot
Richard: of work, but because Zed's codebase very, very heavily works.
Richard: Relies on a combination of features that Rust is really good at,
Richard: such as you have the memory safety, which when you have a wide contributor base,
Richard: we have Zed's open source.
Richard: So it's not just that we have people at Zed working on Zed, but also we get
Richard: all sorts of outside contributions.
Richard: It's really helpful in that context to be able to look at someone's pull request
Richard: and be able to say with a lot of confidence, okay, this is not introducing sneaky memory safety bugs.
Richard: Now, granted, you can make the point that, you know, lots of non-memory safe
Richard: languages have lots of contributors too, like Zig, for example.
Richard: Also Ghosty, which Mitchell Hashimoto made in Zig, has lots of contributors.
Richard: But I think it's definitely a selling point of Rust that when I look at a pull
Richard: request coming into Zed, I can say with a lot of confidence,
Richard: this is not going to introduce some very subtle memory safe debug that I'm going
Richard: to have a really difficult time debugging later.
Richard: Sort of the blast radius of what a new contribution can do in terms of mistakes
Richard: is a lot smaller I do think that's something we benefited from in the Rust version
Richard: of the Roc compiler as well.
Richard: So outside contributors, but also, of course, you know, within the code base,
Richard: it's the same thing. It's definitely a benefit to not have to worry about those things.
Richard: I wouldn't say I've gotten zero segmentation faults or memory safety errors
Richard: in either the original Rust compiler for Roc or in Zed.
Richard: Actually, literally yesterday we had a seg fault in CI.
Richard: And it was it was on well it was it was in our new Windows code base and some
Richard: of the stuff that we're doing is very low level you know interacting directly
Richard: with the operating system graphics APIs and drivers and stuff like that because
Richard: we're it's a very high performance code base and you know,
Richard: Zed is a good example of the classic Rust model of if you're going to have to
Richard: have some unsafe code because you're doing just innately unsafe things,
Richard: maybe for performance, maybe for FFI, whatever, just having it very small and contained is helpful.
Richard: And so, you know, it is helpful to know that the surface area of that is smaller and more contained.
Richard: And if you look at Zed's code base, I think you see what you want to see in
Richard: a classic Rust code base, which is the amount of unsafe is a very,
Richard: very small percentage of the overall code base.
Richard: So yeah i mean i think all those things are great obviously the
Richard: the cargo ecosystem is very large and there's lots
Richard: of stuff you can get off the shelf which is nice there's this classic
Richard: problem in a language where if you were to time travel back
Richard: to when rust 1.0 came out or you know even before
Richard: that everybody would say well ecosystem is
Richard: a downside of rust where they would say like well there's no ecosystem you
Richard: know how can you how can you ignore the gigantic c and c plus plus
Richard: ecosystem whereas of course now ecosystem is the selling point
Richard: i don't know how like people have amnesia about this but
Richard: like it's like every language that has a big ecosystem
Richard: today used to have no ecosystem it just
Richard: grew over time that's just it's a normal part of a language growing so it's
Richard: it's totally reasonable for people to say i don't want to use this language
Richard: right now because right now the ecosystem is small but it's a little bit of
Richard: a pet peeve of mine when people act like that's just this permanent state it's
Richard: like no actually it's the opposite of that it always the ecosystem always grows.
Richard: That's where all the ecosystems you think of as big came from.
Richard: But certainly at this point, the crates.io ecosystem is just,
Richard: you know, very large and you can pull all sorts of stuff off the shelf.
Richard: And that's a selling point. There are some things in Zig that we use at Zed
Richard: that we couldn't get off the shelf in Zig.
Richard: We would have to do like FFI to a C library or a C++ and C++.
Richard: If you're trying to pull stuff off the shelf in C++ and use that in Zig,
Richard: that's a much bigger pain than trying to pull something off the shelf in C and use that.
Richard: See it's a lot easier to interoperate with in Zig so
Richard: yeah the ecosystem also a selling point and i
Richard: think the biggest thing for zed's code base is just the fact
Richard: that you have for lack of a better term drop and because you have drop you have
Richard: reference counting automatic reference counting and we use arc all over the
Richard: zed code base it's just everywhere and we rely on it very heavily we're constantly
Richard: cloning arc things when i first got to the zed code base i was a little bit
Richard: nervous because I would see these .clones everywhere.
Richard: And my experience from writing the Rok compiler in Rust, which used very little
Richard: Arc or RC, was that, oh, if I see a .clone, that's a hotspot.
Richard: That's a big performance potential problem.
Richard: And we had this convention of in the few places where we would use Arc,
Richard: we would do the Arc colon colon clone. So it's really clear,
Richard: like, don't worry, don't worry. It's okay.
Richard: It's just a reference count bump. We're not deep cloning the whole thing.
Richard: But in Zed's code base, if you did that, you would be writing arc colon colon
Richard: clone so so many times it would just be everywhere so what happens instead is
Richard: you just use dot clone because that's way more concise because that's the normal
Richard: way that cloning is used in the Z code base,
Richard: but to do that you do have to have that,
Richard: drop, basically. You need to be able to have automatic, C++ people would call it RAII.
Richard: Zigg, by design, does not have that. And so that's one of the examples of why
Richard: the idea of rewriting Zed's code base in Zigg sounds totally ridiculous to me.
Richard: It would just be a terrible choice.
Richard: Because some projects, one language is a good fit for them, and then other projects,
Richard: another language is a better fit for them.
Richard: So I'm comfortable making the claim that I am happy writing rust at zed as my
Richard: day job and i think that's the correct choice for zed and also outside of work
Richard: having the Roc compiler be in Zig and i think that's the right choice for Roc
Richard: compiler so different projects different needs that.
Matthias: Thing that you mentioned with arc clone and making that explicit really like
Matthias: that idea that's that's such a great idea because yeah you show that,
Matthias: Cost of cloning is really low. And of course,
Matthias: you couldn't do that in all places where you had a lot of usages of ARC,
Matthias: but I wondered if you could build a trade extension for that and you had a ARC
Matthias: underscore clone method on the type that was ARC, for example.
Matthias: And then it would be kind of, you know, explicit, but also weirdly strange.
Matthias: So I'm not 100% sure if you want to go down that route.
Richard: But no, that's... I mean, we're probably not going to do that in Zed because
Richard: I mean, the number of places we would have to switch to that is extremely high.
Richard: But yeah, you can call it bump or something. Like you're just bumping the reference
Richard: count. That's actually a really cool idea. I never thought of that.
Matthias: Yeah, nice. So you wrote a lot of Rust code, probably many tens of thousands,
Matthias: maybe hundreds of thousands, maybe millions of lines of code by now. I don't know.
Richard: Probably hundreds of thousands. I don't think millions. I think I'm under 1 million probably.
Richard: So yeah, the Roc compiler at the point where we decided to switch over and
Richard: do the rewrite was at like 300,000 lines of Rust code.
Richard: Now I did not write all 300,000 lines. There's a lot of other contributors involved in that for sure.
Richard: But at the same time, I also wrote a lot of lines that ended up getting deleted
Richard: or rewritten, et cetera.
Richard: So I think between that and my work at Zed, I'm definitely sure it's multiple
Richard: hundreds of thousands of Rust code.
Richard: I also taught a course on Rust. I taught intro to Rust for frontendmasters.com.
Richard: So that was like an eight hour course just teaching people Rust from scratch.
Richard: I've not taught a Zig course there. I did teach a course but
Richard: but yeah so i have a lot of experience hands-on
Richard: in rust a lot a lot of hours with it and also i've taught
Richard: it to beginners which always requires you know learning a little bit of extra
Richard: detail about things where you sort of have these gaps and as soon as you have
Richard: to explain it to someone in depth where they need to understand it you sort
Richard: of immediately realize where the gaps are and kind of have to go fill some of
Richard: them in so yeah i definitely feel comfortable saying i feel like a Rust expert,
Richard: but not a Zig expert yet, I don't think. I've had a lot less time with Zig.
Matthias: Because that kind of leads me to the next question which is
Matthias: with that level of experience some
Matthias: patterns more or less naturally must have evolved and
Matthias: there are probably things that you would call idiomatic rust that maybe are
Matthias: not written down anywhere or maybe are not in the book what what would you say
Matthias: are some things that you would consider ergonomic or rustic code how does it
Matthias: look like what is it like in practice.
Richard: Yeah well i mean the first thing is of course use unsafe as little as possible
Richard: ideally not at all if you can avoid it,
Richard: I guess there's a lot of using traits for things so for example if you can initialize
Richard: something you probably want to use from and into like that's a kind of a standard
Richard: practice in the ecosystem just so you can make the conversions a little bit more ergonomic,
Richard: similarly if you're going to be formatting it as a string then okay maybe you
Richard: want to give it display you probably want to give it debug I think there's a
Richard: lot of trait centric thinking when I'm writing Rust code, like in terms of like
Richard: what traits do I want to implement, even just the baseline.
Richard: Don't write standalone functions in the top level of your
Richard: module prefer to make an impl for the
Richard: particular type and then you know add it
Richard: to there unless you're writing some function that's really not tied
Richard: to any one particular type kind of the default is
Richard: to think in terms of types and in terms of traits and then in terms
Richard: of impl and putting things on there um also like
Richard: pretty straightforward you know to think about doing like
Richard: taking references to things so like you know ampersand or
Richard: ampersand mutt i say mutt people that said usually say mute
Richard: but i don't know i've always said but so no i
Richard: i since my first experience writing rust
Richard: was with other people who you know were doing rust for the first time we
Richard: kind of developed our own like terminology i guess
Richard: or way of pronouncing things and when you're looking at
Richard: other people's code you don't you don't see how they pronounce it but it said
Richard: we pair program a lot i think i'm the only one who says mutt everybody else
Richard: says mute but it's fine which makes sense it's mutable but anyway um so yeah
Richard: So I think another sort of unwritten rule is that you really should try to avoid
Richard: putting references in data structures,
Richard: which is to say you should really try to avoid having lifetime type parameters
Richard: in your structs or what have you.
Richard: This is something that in the ROC code base, like the original one, we did not really do.
Richard: So we kind of took the approach of, well, yeah, I mean, we don't want to have
Richard: allocations for these things. So let's use Bumpalo for all of our arena allocations
Richard: and then store references to either stuff on the arena or stuff...
Richard: I guess, yeah, it always ended up being in the arena.
Richard: It wasn't really on the stack because then the lifetimes wouldn't work out.
Richard: But yeah, so that's another...
Richard: I don't know unwritten rule i guess is and and it's it's not the
Richard: type of thing where you necessarily need a rule because as we discovered
Richard: if you do that the ergonomics end up being
Richard: pretty annoying because you have this like tick a that's just following you
Richard: around everything you write tick a tick a tick a tick a everywhere so
Richard: i would say it's it's not that you can't do that
Richard: in rust but rather that you know you're asking like what's idiomatic i
Richard: think that's that's something that people tend to avoid is having
Richard: life in lifetime annotations be everywhere it's more like if you're going to
Richard: have lifetime annotations you kind of ideally want them to just be confined
Richard: to a function signature rather than sort of leaking out into
Richard: your data structures and that's kind of i guess a lot of people will solve that
Richard: by using like reference counting or things like that or interior mutability
Richard: or something like that of course at that point as soon as you get into like
Richard: cell and things like that it's sort of like well if you make a mistake then
Richard: now you're potentially you know dealing with a runtime panic which is not great
Richard: or or else having to do all these conditional things.
Richard: So yeah, we did a lot of that and I think kind of learned the hard way that
Richard: that's something that you should probably avoid when you're writing Rust code
Richard: is having lifetime annotations in your structs, like your data structures.
Richard: What else? Yeah, I mean, I guess in general...
Richard: Try to avoid boxing and you know doing
Richard: things on the heap but i would say rust is
Richard: less hardcore about avoiding those
Richard: things than something like c or Zig is so if you look at
Richard: like the lowest level c operating system apis c really
Richard: really like the operating system is is really not going to
Richard: be calling malloc for you like almost ever it's really
Richard: going to be a lot more doing things like okay you need
Richard: to pass in what in rust would be the equivalent of like a
Richard: mutable reference to something where you're saying like give me
Richard: a pointer to this data that you've already pre-initialized and
Richard: also tell me how much you know how many bytes i have to
Richard: work with i'm going to write into there like the the caller says
Richard: here's some memory that i've you know in rust this would be like maybe uninit
Richard: basically and it's like hey give me give me some data i'm gonna you know write
Richard: to it and then i'm gonna give it back to you you know i'm gonna return back
Richard: to you and don't worry the data has been written there and i'll tell you how
Richard: many bytes i wrote into there that's a really common idiom that you see in C,
Richard: at least in low-level operating system type code.
Richard: Whereas in Rust, it would tend to be the opposite. It would be more like,
Richard: no, no, don't worry. I'm just going to take care of that for you.
Richard: There might be some API that's like, give me a mutable reference to something
Richard: and I'll write into it, but that's a lot less common in Rust. So.
Richard: There's a pro and con there on the one hand the apis and rust
Richard: tend to be nicer looking i would say they look a little bit more
Richard: dare i say functional in some
Richard: cases where you're like i'm gonna call this it's gonna do some heap allocation
Richard: with the global allocator and then return you know a string
Richard: or a vec or whatever whereas in c it's more like yeah give me a buffer and it's
Richard: like well what if the buffer is not big enough it's like well then you're probably
Richard: gonna have to call me again and i'll fill in the rest of the buffer after you
Richard: resize it for me or something like that so you don't tend to see that type of
Richard: thing in rust it tends to be more open to doing silent allocations than than see your Zig now.
Matthias: From experience i know that quite a few people that i would deem to be experts
Matthias: in rust or very experienced are pretty lightweight on design patterns for some
Matthias: reason and i wonder if you also saw that in working with larger code bases and
Matthias: where you stand on that side of the spectrum.
Matthias: So do you use a lot of design patterns in your code or are you also just like
Matthias: leaning into what you mentioned, structs, traits, and combining those?
Matthias: And do the design patterns evolve more or less naturally for you or is it something
Matthias: that you consciously think about when you write code?
Richard: So let's be a little bit more specific. When you say design patterns,
Richard: are you thinking about sort of the concept as in like, you know,
Richard: patterns of design that come up like, you know, techniques and things like that?
Richard: I mean, of course, in that sense, I would just call those, I don't know,
Richard: idioms or something like that.
Richard: Usually when I think design patterns, I'm thinking like Gang of Four,
Richard: observer pattern, you know, things like that, visitor pattern and whatnot.
Richard: So certainly I'm not thinking in terms of gang of four stuff.
Richard: Like I did a lot of enterprise Java early on in my career.
Richard: And that based on that experience, I've kind of, I don't know,
Richard: sampled the object oriented style and I've sampled the functional style and
Richard: I've sampled the imperative procedural, not object oriented style,
Richard: which is what I would put Rust and Zig in that category.
Richard: And my conclusion is that imperative procedural is fine. Functional is fine. Yeah.
Richard: Object-oriented is a mistake i i i've been trying to sugarcoat that more and more over the years,
Richard: trying to be diplomatic about it but for the purposes of this podcast i'm just
Richard: going to say yeah i don't think any of that was the right direction i think
Richard: it's going to turn out to be a dead end in programming that you know people
Richard: are going to look back on as like that was the thing that people used to do
Richard: i don't think that's the future of programming so yeah i i'm happy to have moved past that.
Matthias: Oh that's interesting because you use different ways to encapsulate code then
Matthias: And you use namespaces and modules and freestanding functions to group that logic.
Matthias: But don't you still need some way to hold state, like structs or things where
Matthias: you can maintain some sort of order of the events that come in,
Matthias: like as in an actor system or so?
Matthias: It's kind of a pretty bold statement to say OOP was a mistake.
Matthias: What's the alternative then?
Richard: Well, it depends on who you ask, right? So if you talk to some of the like Casey
Richard: Muratori and Jonathan Blow and people like them who do a lot of like high performance
Richard: game dev saying OO it was a mistake.
Richard: Is there just like, yeah, so let's talk about something interesting.
Richard: You know, like we know we've known this for a very long time.
Richard: Yes. In the broader programming world, I agree that it's a bold statement,
Richard: but there are quite a lot of people who are just like, yeah,
Richard: of course it's, it's not controversial at all.
Richard: So yeah, I mean, like you mentioned encapsulation. So for example,
Richard: encapsulation is a special case of modularity. So modularity is the idea of the boundary.
Richard: It's like saying it's just pub and private, right? Public and private interface.
Richard: So you can say like, here are the things that I'm exposing. Here are the things
Richard: that I'm intentionally not exposing.
Richard: Nobody outside my module can access my private things encapsulation just
Richard: means modularity but in an object-oriented context
Richard: it's like modularity applied to classes and objects
Richard: well if you don't have classes and objects and you just got like
Richard: you said structs and rust like modularity is
Richard: fine you can you know all we're talking about there is just like
Richard: did i decide to make this field on my struct pub
Richard: or not right everything just sort of follows from
Richard: that it's the very basic thing of saying i'm intentionally hiding
Richard: these implementation details and the reason that i'm hiding these
Richard: implementation details is that for example i'm trying
Richard: to create an invariant that i want to be enforced by the compiler like
Richard: i want to make sure that nobody is you know reaching in and messing with these internals because
Richard: if they did it would violate my assumptions and i want to really hardcore communicate
Richard: that by giving anyone who tries to do that a compiler error or i might be making
Richard: a library and i might want to say i want to have really strong backwards compatibility
Richard: guarantees but i might want to change the internal structure of this same thing
Richard: right i'm going to make these things pub and these things private.
Richard: That's all it is that's that's modularity and then encapsulation is just modularity
Richard: but i'm specifically talking about modularity at the level of a class and since
Richard: Rust doesn't have classes i would argue that technically speaking Rust doesn't
Richard: have encapsulation Rust just has modularity,
Richard: somebody might but people use these terms pretty interchangeably i think in
Richard: a lot of cases like a lot of people well first of all even though the term modularity
Richard: i think might have come first i don't know now we're getting back into like
Richard: alan k coined the term object oriented in the 70s and you know nicholas virz
Richard: was working on modula also in the 70s i'm not sure exactly.
Richard: Which term technically came first, but certainly the term encapsulation is more popular today.
Richard: So I think that's what more people associate with that boundary system.
Richard: But I think it's worth noting that from a historical perspective,
Richard: modularity is the thing that everybody seems to agree that they want now.
Richard: Literally right now, I think on Hacker News yesterday or the day before,
Richard: there was a front page article about modules in C++ and when are they coming?
Richard: So an observation i would make is that every language
Richard: that just had encapsulation just to say the only way
Richard: to do public and private was at the class boundary every single
Richard: one of them has ended up wanting a module system every
Richard: i should say every popular one okay like i'm sure
Richard: there's some you know obscure languages that don't have it i'm sure small talk
Richard: will never you know consider adding a module system but but i
Richard: mean c++ java right like all these languages have
Richard: ended up having some separate mechanism so it's like actually we don't
Richard: want only to be able to do that through classes and that
Richard: makes sense modules are a really nice idea but the question becomes if
Richard: you have public and private at the module level do
Richard: you also need a separate class thing which
Richard: also has its own public and private or is module level sufficient and it seems
Richard: to me to be the case that module level turned out to be you know sufficient
Richard: and you know Rust is an example of a language that does not have objects does
Richard: not have classes unless you want to count like you know whatever din objects dyn you.
Richard: Like trade objects and stuff like that but that's just the name they chose for
Richard: that that's not like they are not objects in the object oriented sense they
Richard: don't have classes they don't have inheritance or any of that stuff so yeah
Richard: I don't know I don't want to get too far in the weeds on that but I guess to sum it up I would say that.
Richard: Actually, I gave a whole talk on this. I gave multiple talks on the subject
Richard: of object-oriented and whatnot, but I gave one called The Next Paradigm Shift
Richard: in Programming and also The Return of Procedural Programming.
Richard: The Return of Procedural Programming is a very on-the-nose talk about OO got really big.
Richard: If you look at what are the biggest new languages that have come out that are
Richard: getting popular, they break down into two categories.
Richard: One is they're just a plus-plus version
Richard: of an already popular language so for example kotlin is basically
Richard: java plus plus it's like they took java and then intentionally have
Richard: seamless java interop and so you
Richard: could not possibly make a language that has seamless java interop without having
Richard: it be object-oriented because java is extremely object-oriented but if
Richard: you look at if you exclude those and say like languages that are not coupled
Richard: to an existing already popular language what are
Richard: the greenfield languages like and there's only two
Richard: there's rust and there's go those are the two languages that
Richard: are getting popular that are greenfield not based on
Richard: and coupled to an existing already popular language and neither
Richard: of them are object-oriented at all they're just procedural languages and
Richard: that's hence the title of the talk the return of procedural programming so
Richard: if someone wants to make the case that object orientation is the future you
Richard: might want to ask why is it that the only new popular object-oriented languages
Richard: that are coming out and gaining actual traction in the real world why are they
Richard: all coupled to legacy object-oriented languages and nobody's making new object-oriented
Richard: languages from scratch that are seeing popularity.
Matthias: I can get behind that. Never seen it this way, but the way you explained it makes a lot of sense.
Matthias: We will link those talks in the show notes.
Matthias: I guess Rust kind of found a nice balance there because that's also somewhat
Matthias: what I consider idiomatic, Rust,
Matthias: to make use of separate input blocks, to make use of composability with traits and so on.
Matthias: And you don't always need trade objects and that sort of thing.
Matthias: Ensure a lot of things that compile time and make it still composable right and still have,
Matthias: all the ways to do different
Matthias: kinds of visibility at your disposal you can have
Matthias: pop you can have pop crate you can have public modules and so on so that's it's
Matthias: pretty cool i'm sure we could talk about this for a long time but i would like
Matthias: to shift gears too the first time where you noticed that Rust might not have
Matthias: been the right choice for the language that you were building.
Matthias: What was the first time when you noticed, well, no, I need to think about an alternative to Rust?
Richard: That's very easy. We talked early on about how a big part of programming language UX is compile times.
Richard: They got slow. When we had a small Rust code base, their compile times were
Richard: fine. Everything was nice and snappy.
Richard: And as it got bigger and bigger, they got slower and slower.
Richard: And now they're just quite slow.
Richard: I just did this morning. I did a scratch build of the Rust code base and it
Richard: took like 30-40 seconds somewhere in there and a rebuild still took about 10
Richard: seconds and in contrast our Zig project,
Richard: which granted this is apples and oranges. The Rust code base is like 300,000 lines.
Richard: A Zig rewrite is currently at about 100,000 lines.
Richard: The scratch build of the Zig one was like 13 seconds or something like that and then the,
Richard: the incremental rebuild was like 1.3 seconds. Now that's worth noting that that's
Richard: going to get much, much faster in the future because I'm working on an ARM64 Mac.
Richard: Zig has an alternative backend to LLVM, but it's only X64 right now.
Richard: The ARM one is still a work in progress. It hasn't shipped yet. It's not stable.
Richard: And once it does, then that 1.3 second rebuild is going to get much smaller still.
Richard: And also Zig still doesn't have full, like they have not fully realized their
Richard: goals in terms of incremental rebuilds, whereas Rust, I would say,
Richard: has at this point based on the constraints of the language with crates being
Richard: the smallest compilation unit rather than individual files.
Richard: So given all of that, it's already the case that we're seeing a much bigger
Richard: gap between Zig and Rust than sort of linear in terms of lines of code.
Richard: Like if all those being equal, Rust code bases, you know, 300,000 lines versus
Richard: Zig one being 100,000 lines, you would think that the Zig one would be maybe
Richard: three times faster, but not 10 times faster for like incremental rebuilds.
Richard: And also, it's not just that it's already 10 times faster, which it is,
Richard: it's one-tenth the incremental compilation time, but also that it's going to
Richard: get much faster in an upcoming release, like probably the next one after the current release.
Richard: When I'm assuming the ARM64 one's going to ship, and actually people who are
Richard: working on the raw compiler in x64 processors are already benefiting from that
Richard: much faster compilation time because that one already has shipped.
Richard: So meanwhile like on
Richard: the rust side i mean lvm is a very very known culprit
Richard: for making slow builds and unfortunately you
Richard: have to you can't just you know do like check like cargo
Richard: check you know that's not the whole thing you want to run your tests and in
Richard: order to run your tests you have to do code generation and that requires lvm
Richard: in rust there is a crane lift back then but i'm not kidding when i started Roc
Richard: wrote the first lines of code the
Richard: crane lift back in for rust was work in progress, it still hasn't landed.
Richard: So that was 2019. And maybe it's right around the corner, but I can only hold
Richard: my breath through so long.
Matthias: Yeah. And I guess you probably used all the tricks at your disposal to make it faster.
Matthias: You probably went through a lot of tutorials and tried a few things.
Matthias: It's probably optimized to the max by now, the Rust code that is.
Richard: I wouldn't say we went all the way to the max. We certainly tried a lot of things.
Richard: So like the really obvious one that everybody says, oh, just try mold.
Richard: And said mold made no difference whatsoever for us i mean we like
Richard: we didn't even bother enabling on ci because we had people who are
Richard: using like daily driving linux and like oh let's try it
Richard: out they're like i mean it's a little faster like
Richard: you know mold for linking we tried splitting up
Richard: our crates along more boundaries etc i mean
Richard: really the the overall feeling that we
Richard: ended up having was that even if we
Richard: do like use all the maximum number of tricks and
Richard: and try to like contort the code base around just the number
Richard: one goal is trying to get it to build as fast as possible it's
Richard: just still not going to be anywhere near as fast as Zig is building i mean the
Richard: Zig team is in the progress of working towards hot code reloading where like
Richard: you make a you're running your Zig program and while it's running you make it
Richard: you know you save and it's like instantly updated with the running program.
Richard: That's i i it's inconceivable to me
Richard: that Rust would ever have that like in my lifetime i'm not saying it's
Richard: impossible i'm just saying that just based on
Richard: the i don't know the way things are organized right now
Richard: and i've talked with a lot of people in the rust project about compile
Richard: times there are definitely some heroes who are like really trying
Richard: to fight the good fight you know and trying to make like
Richard: compile times a major priority but unfortunately it
Richard: really it feels like that's not
Richard: the majority view right now it's it's the majority view is
Richard: not that compile times are a major priority or
Richard: need to be a major priority or maybe it's that people think
Richard: that they should be a priority but their ambitions for how much of an improvement
Richard: they think are possible is way below what the what the ambition level is for
Richard: Zig like when i talk to Rust core team members i've told them this so this is
Richard: not i'm not you know i'm not saying anything here that I haven't said to people who work on Rust.
Richard: When I talk to them about the compile time situation, the response that I usually
Richard: get is something along the lines of, here's why it's really hard to make it faster.
Richard: When I talk to Zig people about compile times, it's the exact opposite.
Richard: They're like, I'm so sorry that it's not already as fast as the hardware could possibly make it be.
Richard: We're working really, really hard on making it be that whatever your hardware
Richard: is, we're using it to the maximum extent to give you the absolute lightning fast compile times.
Richard: The attitude difference is just totally night and day and this was something that i picked up on,
Richard: ever since i met andrew kelly who created Zig at a conference is
Richard: just there's this big attitude difference in
Richard: terms of how important compile times
Richard: are to the roadmap every year i fill out the rust state of
Richard: rust survey and you know i'm outing myself
Richard: you know whatever somebody reads that they could tell who if it's me you
Richard: know even if i didn't put my name on it like they ask about
Richard: oh do you want this feature do you want that thing stabilized you want this that every year
Richard: i'm just like i don't care i don't care i don't care i don't care just make it faster all
Richard: i care is compile times i don't care if this gets stabilized or that
Richard: gets stabilized or this is available in language everything in rust is already
Richard: like from a feature perspective fine like all these little like oh what if what
Richard: if you have like async functions i'm like i don't care i'll just put them in
Richard: the block it's fine like i make an async block of closure it's like i don't
Richard: i don't care i just care about i want the compile times to be a lot a lot a lot lower than they are,
Richard: but of course I don't seem to be in the majority on that in terms of Rust users
Richard: either it seems like to be totally honest a lot of Rust users.
Richard: Are okay with the compile times being the way they are and maybe that's because
Richard: they're working on smaller code bases I don't know or maybe it's because,
Richard: they're coming from like a Java or a C++ background and they're not they're
Richard: like what's the problem but coming from an Elm background and also now you know
Richard: having experienced like Zig compile times I'm like I just I don't,
Richard: I can't not be bothered by it a lot, all the time, like knowing what's possible.
Richard: So yeah, I don't know. I've ranted on my podcast, which is software unscripted,
Richard: by the way, a lot about Rust compile times.
Richard: We were thinking about a rewrite anyway. I don't know that if we would have
Richard: like seriously discussed doing it in Zig if Rust compile times were fast.
Richard: I think we would have just been like, no, we're going to rewrite,
Richard: but we're going to rewrite it in Rust again.
Matthias: Okay. I'm probably in the camp where compile times are not that big of a problem
Matthias: for me nowadays it used to be a problem and then two things happened first modern
Matthias: arm hardware is pretty decent at compiling Rust so you have m4 and it's it's
Matthias: much better than it used to be,
Matthias: and the other part was the Rust compiler did
Matthias: actually get faster since 1.0 i hear that
Matthias: a lot from people that come from functional programming and
Matthias: from game dev for people that need fast
Matthias: feedback loops because this is kind of
Matthias: a development model that doesn't really fit well
Matthias: or perfectly well right now with rust i feel like
Matthias: if i were to write a game from scratch i would also be cautious to maybe use
Matthias: rust or not i wouldn't be sure but is that true like does that ring true to
Matthias: you where you say it's because of your background maybe even before using Rust,
Matthias: you learned that there's a different way to build software.
Richard: I certainly think that the degree to which compile times bother you would depend,
Richard: sort of obviously, on what you're used to and what you, I don't know,
Richard: think of as sort of possible or normal.
Richard: Like if I'm used to Elm and like, you know, sub second, you know,
Richard: recompiles and stuff like that, then yeah, I mean, it's going to bother me when
Richard: I'm waiting 10 seconds, you know, to, to be able to build my thing or to run my tests.
Richard: Similarly, I mean, like at Zed, it's, it's just really obvious.
Richard: Like the classic example of the, the really obvious pain point here is I'm like,
Richard: I just need to scoot this thing over by two pixels because it's a little bit off.
Richard: I just need to make a little tweak here and I'm just sitting there waiting for
Richard: that. I'm like, if I were using a browser, JavaScript or something like that,
Richard: I wouldn't even need to think about this. I would just be like, refresh the page.
Richard: Now, granted, in modern front-end development, a lot of people have TypeScript
Richard: and Next.js and this and that, but those are self-inflicted wounds.
Richard: You have the option to not do that to yourself.
Richard: In Rust, there is no such option, as far as I'm aware. There's no way to say,
Richard: I have this big Rust code base.
Richard: I'm just making this small tweak to this one thing. I think if you wanted to
Richard: do something like that, But you would probably need to, I don't know,
Richard: do something like reorganize, like really aggressively reorganize your crates
Richard: in a way where you can try to just make it so that, I don't know,
Richard: the caching works out or something like that.
Richard: I mean, we've tried to do some of that at Zed, obviously, because compile times are such a pain point.
Richard: But yeah, if you need to make a change to something deep in the bowels of our
Richard: code base, it's always going to be super slow.
Richard: Something that's dependent on by lots of things. there's just no way to get
Richard: it to be fast whereas again like if you have a giant javascript code base not
Richard: typescript you know where you have to do the builds and everything but just
Richard: have a you know giant vanilla javascript code base obviously that has its own
Richard: problems on many many levels
Richard: but in terms of feedback loop it's still just going to be very fast and yeah
Richard: so if if that's the type of thing that you're used to is this sort of javascript
Richard: or elm like feedback loop it's just very frustrating and innately i think to
Richard: to work on a large rust code base and to have these slow feedback loops.
Matthias: Yeah. Zed has sort of their own UI framework as far as I remember,
Matthias: but there are systems like Dioxus and Laptos now that have hot reloading and
Matthias: it's an experimental feature,
Matthias: but they somehow made it work such that you can make certain modifications in
Matthias: your code and it's kind of guarded by a certain way to write things.
Matthias: Not everything is hot reloadable, but some components are
Matthias: but of course you're not
Matthias: writing some sort of user interface with
Matthias: Roc you're writing a compiler so that's completely different
Matthias: right yeah and i i can see how that
Matthias: might be frustrating where make a single line change and then
Matthias: you wait for 30 seconds for a clean build
Matthias: and so on so that can can certainly be true have
Matthias: you considered any alternatives other languages that
Matthias: maybe have faster compile time spoiler or not maybe that
Matthias: much of a paradigm shift like maybe i don't know
Matthias: microsoft for example they wrote rewrote c
Matthias: sharp in rust but also typescript in go or there might be yeah actually typescript
Matthias: and c sharp might also be alternatives i don't know if you want to write a compiler
Matthias: in typescript necessarily but perhaps c sharp i don't know or have you considered
Matthias: any other languages other than Zig as well for the rewrite well.
Richard: This gets back to the the performance ceiling right.
Matthias: So like.
Richard: I said it's been a hard non-negotiable goal that Roc the Rocs compiler,
Richard: needs to be as fast as possible it needs to be really really fast it needs to
Richard: not just be like kind of fast it needs to be extremely extremely fast that's
Richard: a really really important thing to me about the compiler which means that any
Richard: language of the garbage cluster immediately out so go immediately out c sharp all of them you know,
Richard: no dice so really i mean the only contenders
Richard: i would say would be like rust Zig or
Richard: some other language that has basically supports memory
Richard: unsafety so even like when we got
Richard: far like very far into the the rust
Richard: compiler like the rust implementation of the Roc compiler we
Richard: were using unsafe more and more and using it in the rusty way where you know
Richard: you try to like minimize the blast radius but to do things like destructive
Richard: arrays and whatnot and i don't know maybe we should get into that but yeah like
Richard: there is like even though like so Roc also has a goal of being for a language
Richard: that automatically manages memory for you and guarantees memory safety.
Richard: It tries to be very very fast and like i said like you know we want like run
Richard: faster than go is a goal one of the things that that makes me realize is just
Richard: how important memory unsafety is to performance like basically there are some
Richard: things that you cannot do or cannot do ergonomically,
Richard: if you have a hard requirement of like memory safety is
Richard: enforced there are just some things that require memory
Richard: on safety if you want them to go fast because in order to enforce memory
Richard: safety you have to do runtime checks so really really easy
Richard: example of this is bounce checks so sometimes
Richard: the compiler can align this but sometimes they can't like the way
Richard: that rust gets memory safety around
Richard: buffer overruns is just that you know
Richard: if you have a slice or you have a vec then you do like an
Richard: access at a particular point in there that's going to be checked
Richard: at runtime and if you do like the square brackets then it's
Richard: going to panic if you have an index out of bounds or if you
Richard: do like a you know dot get then it's going to give you back an option then you
Richard: have to handle you know what if it was inbounds what if it was out of bounds c
Richard: does not have that of course rust does have the unsafe equivalent of that but
Richard: then you have to wrap it in unsafe and then you avoid the bounce check well
Richard: the point is that if you want maximum performance you don't want that bounce
Richard: check you want to just not do that and the downside is if you make a mistake
Richard: then now you have undefined behavior so obviously there's a trade-off there.
Richard: But in a language like Roc, we don't offer the unsafe option.
Richard: Like even if you're in like the hottest of hot loops and you're like,
Richard: no, I really, I can, you know, the compiler is not able to elide this balance
Richard: check and the balance check is actually causing problems for me in practice somehow.
Richard: You're stuck. You just like, sorry, we don't support that. And so the performance
Richard: ceiling on something like Rust or C, because, you know, Rust does allow you
Richard: the option to say, no, you can do it without the balance check if you're really, really sure.
Richard: C just doesn't have the balance check in the first place. and Zig much like
Richard: rust has the option of yeah you can do it with it without the bounce check,
Richard: Zig actually will do it with like a well
Richard: so you can when you're compiling Zig has different optimization
Richard: levels one of which is optimize safe which is basically like what rust does
Richard: so it's like always have the bounce check you can also have optimize fast which
Richard: basically means we'll do the bounce check and debug builds but in release builds
Richard: we will not do it kind of similar to how rust will do panic on overflow and
Richard: debug builds but then in release builds it'll just,
Richard: let the number overflow and just the energy just wraps around Zig does that
Richard: same thing for like memory access if you compile with release fast as opposed
Richard: to release safe release safe we'll just keep them so basically those types of
Richard: things are not accessible in a language like c sharp or something like that
Richard: unless you want to drop into cffi and at that point i'm like well,
Richard: if i'm going to do ffi why don't i just write it in one language and,
Richard: So that's the type of thing that I see as sort of a reason that we did not consider
Richard: languages like C-sharp or Go.
Richard: Even though they are plenty fast for garbage-collected languages,
Richard: however fast they might be, I want that maximum performance ceiling to be available.
Matthias: One of the killer features that keeps coming up in every single discussion I
Matthias: have with people that compare Zig and Rust, which are fundamentally two different languages,
Matthias: is that Zig has this very nice concept of comp time.
Matthias: And in Rust, we have not so much.
Matthias: We have derives, we have a build RS, and we have macro rules.
Matthias: But that's more or less what we can do.
Matthias: So from your perspective, knowing both concepts, what is your current feeling about comp time?
Matthias: Is it something that Rust should add? Or is it something that is very much native
Matthias: to Zig and the way Zig works? And there are better alternatives in Rust?
Richard: I don't think you could retrofit comp time onto rust i
Richard: don't think that would make sense um the thing that's really
Richard: cool about the way that Zig uses comp time primarily
Richard: i would say is that Zig has
Richard: comp time instead of a whole laundry list
Richard: of features that rust has to try to do the same kind of
Richard: job so you'll learn this one concept and i
Richard: mean there's some different aspects of the concept it's not like it's this you
Richard: know oh here's comp time it runs a compile time the end there's a
Richard: whole like supporting ecosystem around that like okay if i want to do type
Richard: introspection that's just like a thing i can do at compile
Richard: time but you do actually have to go learn like how the type
Richard: introspection stuff works kind of like how in rust you
Richard: have to go learn proc macros though proc macros are a lot more complicated than
Richard: comp time which i would say is the other nice thing about comp time it's not
Richard: just that it's one powerful feature that takes the place of several other features
Richard: in rust but also that it is conceptually pretty simple the learning curve is
Richard: not as high as something like, again, I'll pick on proc macros.
Richard: That said, I don't want to say that it's all upside and no downside.
Richard: I mean, one of the things that is a, I don't know, thing that I miss from Rust
Richard: when I'm working in Zig is that because Rust has like full parametric polymorphism,
Richard: including of arguments,
Richard: Rust types tend to be more self-descriptive than Zig types are.
Richard: That's like pretty common in Zig to see something where at the type annotation
Richard: level, it says something like, oh, this takes in any type.
Richard: Now this is not the same thing as like in typescript
Richard: for example you have a type called any it's just this magical thing that
Richard: like you know you can give it anything and it's all going to work out unless it
Richard: crashes at runtime or gives you horrible things that's not
Richard: what it means what it means is just that this is something that's going to be
Richard: resolved like this type is going to be resolved at compile time rather than
Richard: being like fixed to a hard-coded type that you've written down so you will still
Richard: get a compiler error if you misuse that function you try to give it a like incompatible type.
Richard: But again, the thing that I miss from Rust is that in Rust, I would be able
Richard: to see a type written out.
Richard: So just at a glance, I can say, what does this function take?
Richard: In Zig, it's much more common than it is in Rust because it's much more common
Richard: in order to find out whether or not something succeeded or failed,
Richard: I actually need to do a build. So the analogy here would be macros and Rust.
Richard: Sometimes I have some code and I'm like, okay, I'm looking at this.
Richard: And based on looking at it, I'm not totally sure if this is going to compile or not.
Richard: I need to actually compile it to figure out if it's going to work or not,
Richard: because it has to resolve all the macro stuff.
Richard: And then based on how the macros resolve, okay, maybe it's going to turn out
Richard: that something did or did not compile, and then I'll get an error.
Richard: So I'm still getting the error at compile time. But of course,
Richard: I would prefer to just have it be more visually obvious where
Richard: i can just look at it and say like this is definitely going to work or this isn't going to
Richard: work without actually having to wait for the compiler to you
Richard: know go through the macro expansion to be able to tell whether or not it
Richard: compiled that's kind of that analogy i think
Richard: applies to Zig's comp time as well where there is a higher number of cases where
Richard: i can't just look at it and know for sure like what its type is or what types
Richard: this function accepts or doesn't accept i have to wait for the compiler to go
Richard: through and give me that feedback So it's sort of like the absolute fastest
Richard: feedback loop is I just look at it and I can tell from, you know,
Richard: my intuition, my experience with the language.
Richard: The second fastest feedback loop is compile time. Then the third fastest would be runtime.
Richard: So there's more things in Zig that are in that second case of I can't just look at it.
Richard: I have to actually run the compiler than there are in Rust when it comes specifically
Richard: to type annotations because comp time is used in type annotations like that.
Richard: So this is kind of an inside baseball thing, but I think anyone who's used both
Richard: languages would pick up on that as something like, yeah, I do appreciate the
Richard: conceptual simplicity of comp time and how it can take the place of all these
Richard: other language features,
Richard: make the language simpler and learning curve and all that good stuff. And it's very powerful.
Richard: There's things that you can use comp time for in Zig that I guess I haven't
Richard: maybe thought through it, but it seems like it would be harder to try to wrangle
Richard: all the different Rust features together to do the same thing.
Richard: But that is a downside is that you don't get.
Richard: Some of your type annotations are just not as self-descriptive and in order to tell
Richard: what this function takes i either need to go read the implementation or more
Richard: likely i need to read the comments for the function that's like okay here's
Richard: what you can give this thing right but i can't tell just by looking at the type
Richard: annotation i actually do need to go read some documentation
Richard: just to know what i can pass to this that will compile at compile time just like with a macro.
Matthias: I'm not an expert on this but as far as i know six comp time also takes the
Matthias: outer scope into consideration if something was defined before the comp time,
Matthias: call then you could access that i don't know if that is true maybe correct me
Matthias: if i'm wrong but there is a crate called crab time now which.
Richard: Oh yeah works for us and.
Matthias: It it takes a piece of code and then compiles that in a separate project and
Matthias: then it inserts the result into your project.
Richard: Yeah so it does not.
Matthias: Access the outer scope though.
Richard: But again like i mean going back to like to
Richard: me the the cool part about comp time is it
Richard: has something in common with functional programming which i love about
Richard: functional programming which is the subtractive aspect it's like it's
Richard: the thing that i most like about comp time and
Richard: Zig is all the features that Zig does not have because it
Richard: has comp time so if you add comp time to rust which
Richard: already has all those other features it it just seems like it's
Richard: it's moving in the wrong direction it's like well no the thing that i
Richard: like is the the reduced feature set smaller set of
Richard: simple primitives similarly to how you know if you take something like javascript
Richard: or typescript you're like oh let me add some more functional programming stuff
Richard: and then it's like well no but i what i like about it is the subtracted the
Richard: smaller tool set i want a smaller tool set of simple primitives i don't want
Richard: to just add yet another way to do it into something that I think is already
Richard: too complex in the JavaScript ecosystem.
Matthias: Yeah, I can fully get behind that.
Matthias: And also, whenever you talk through such a technical problem,
Matthias: or maybe a technical decision that was made, it always feels like your opinion
Matthias: is very balanced. You don't really take any of both sides.
Matthias: It's just that you pick what works best for you and for the team, right?
Matthias: And that's very refreshing to hear as well, because everything is backed by
Matthias: facts and backed by a lot of knowledge as well. so that was pretty impressive
Matthias: i guess we could talk about that for ages.
Richard: Unfortunately we did.
Matthias: Run out of time but there's one final question that i commonly ask at the end
Matthias: which is what is your message to the rust community.
Richard: I think the biggest thing would be focus on the end user,
Richard: i think it's it's easy because rust is such a big language with so many different
Richard: features and there's so many different competing concerns you can have in terms
Richard: of like i need to balance it's like making this safe and also making it well
Richard: tested and well structured and easy to maintain,
Richard: there's all these different things that you could be thinking about and i think,
Richard: focusing on what's the end user gonna you
Richard: know get out of my program that's the most important thing that's got to be
Richard: the north star and don't lose sight of that when you're thinking about all these
Richard: other things that you as a programmer could be thinking about and i think that's
Richard: something that zed really embraces which i really appreciate about zed it's
Richard: like we brag about things like Like, you know,
Richard: this is a code editor that runs like 120 frames per second when you're like
Richard: scrolling through your tabs, you know, as switching like code editors as fast
Richard: as possible and things like that. And I think that's how it ought to be.
Richard: It shouldn't be that we're bragging about, you know, Z is innately good because
Richard: it's written in Rust, but rather that Z is really, really fast and writing it
Richard: in Rust is the way that we achieve that.
Matthias: That was pretty amazing Richard thanks so much for taking the time where can
Matthias: people learn more about Roc.
Richard: Yeah so Roc does R-O-C it's
Richard: named after the mythical bird not the not the rock like the
Richard: you know inanimate object or the genre of
Richard: music so roc-lang.org like i
Richard: said we're in the middle of a compiler rewrite so you can definitely try it out but
Richard: stay tuned i would say like you know this is going to come
Richard: out i'm assuming somewhat before advent of code 2025 but
Richard: we're hoping to have the new compiler ready to
Richard: rock for pun actually retroactively intended um
Richard: ready to rock for advent of code 2025 so
Richard: people can try it out and so far we're on track to be
Richard: able to do that but yeah there's going to be a lot of new design changes
Richard: and awesome stuff for the language it's going to be easier to get
Richard: into especially for beginners and people can
Richard: look forward to all that but if you want to get involved sooner than that or certainly
Richard: if you want to contribute to the compiler or donate to what we're doing we
Richard: have a non-profit foundation set up that people we can donate through so it's
Richard: tax exempt in the u.s and yeah all that is at roc-lang.org and of course if
Richard: you want to follow any of the rust stuff i'm doing check out zed zed.dev it's
Richard: been my daily driver editor for years now i love it and it's been just getting better and better.
Matthias: Yeah that was amazing greetings also to Conrad Irvin and Folkert de Vries who
Matthias: used to be guests as you mentioned And Richard, thanks so much for taking the time.
Richard: Thank you.
Matthias: Rust in Production is a podcast by corrode. It is hosted by me,
Matthias: Matthias Endler, and produced by Simon Brüggen.
Matthias: For show notes, transcripts, and to learn more about how we can help your company
Matthias: make the most of Rust, visit corrode.dev.
Matthias: Thanks for listening to Rust in Production.