Implementing a programming language in a systems language like Rust reveals fundamental differences in type systems, memory management, and error handling compared to higher-level languages. Rust's strong type system forces explicit handling of all cases at compile time, making it harder to overlook edge cases but providing better error messages. The Cell language demonstrates how a simple, Lisp-like design with minimal type system and control flow can be implemented in 200-400 lines, while Rust's strict rules about self-referential objects and lifetimes require careful design patterns like the Pin type to handle complex scenarios like async programming.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Jez returns for programming language chat!Added:
Hello, welcome back. Um, I'm joined by someone you may remember if you were here ages ago, Jez. Welcome back, Jez.
>> Thank you. Hello.
>> And, uh, we're hoping to do a bit of coding together. We're going to see if we can code some of G unzip. Like, we're going to like figure out how G unzip works and then code some of it. Probably not much of it to be honest.
>> Probably not much of it, but some. But first, last time you were on Jazz, we talked a bit about your implementation of a programming language that I designed ages ago called Cell, which was designed to be easy to implement. And I thought we could have a quick update on a how you're getting on and b whether it really is easy to implement.
>> Well, yes, I think I have finished.
>> Whoa. Um, so when when we spoke before, I had just started and it was kind of the first time I'd done any Rust and I was doing a lot of kind of floundering around because Rust didn't work the way that I was expecting programming languages to work.
Um so things that I would n so most of you know most of my programming has been in C++ and Python and JavaScript and Java and C# and all those languages are relatively similar in that uh well if we take an example from the code in front of this if I want to hang on to a reference to an iterator for example I can do that.
>> Mhm. But the way that uh because Rust regards an iterator as a trait rather than a subclass right rather than an interface. So like you you don't subtype an interface >> subtype iterator. You implement it for your type >> which is not quite the same thing. You you you take hold of it and you hold on to it in a different way or you reference in a different way. And I was triggered over that a lot.
>> Right.
And I started I would write things and then it wouldn't compile and the IDE would say maybe you need dine in here.
>> Yeah.
>> And so I put dine in there and then maybe but actually I didn't what I didn't need I didn't need that at all.
What I needed was to make the whole thing generic >> right on it. Yes. Yes. Okay. That makes sense. Yeah. Yeah. Yeah. And then then a whole load of that you've been wrestling your way through like mutable dine references in boxes and all and and suddenly you just go oh no this just needs to be generic on some I which is an iterator which is >> so this is what you've done here. Okay.
>> Yeah. And then then it all just go all the complicated stuff just goes away.
>> Right.
>> That makes sense. Um, >> yeah.
>> So, I stumbled over those kind of things a lot. And the other thing that I was still wrestling with at the time was options of results.
>> Right. Yeah.
>> Result or or results of options.
>> Yeah. Yeah. Yeah. Yeah.
>> Okay. Because because you've got there often you've got kind of you got two combinations of two, but there's always one which you never would get.
>> Yeah. Right. Yeah. Not always.
>> Cuz if it's an error, well, no, but if it's an error, then you're you you know what I mean? If the outermost one is if it's if it's okay or error and then then you're okay and then you've got something or you haven't. But if it's an error, then you never look inside.
>> You won't have an Yeah. You won't have an an option. You won't have Yeah.
Exactly. Right. Yeah. Yeah. Okay. I see what you mean.
>> So and and that and I I h I am familiar with that because a language we have at work which has a result type and an option type and actually there were huge huge arguments which actually ultimately weren't really very important about whether we needed both an option or a result >> or whether they were actually the same and just synonyms for each other and all.
>> So but anyway once you get used to it >> great.
>> That's fine. That's fine.
>> Yeah. And it's like uh Have you done Haskell before?
>> A teeny tiny teeny weeny bit.
>> Same here. Yeah. But I think some of the I think if you're more familiar with Haskell, some of this stuff might be might come easier to me at least. Yeah, >> some of the the the stuff that that I did like um and it is something I I do tend to do in language languages languages which allow is this kind of um people used to call it a fluent interface but this kind of pipelining thing.
>> Mhm. So you see you see it there selfcharts next and that returns an option and so then you do and then >> and then so your error handling kind of disappears away. So you try a thing and then you've got this or else change. So it's just >> and it's going to >> pop out the bottom the or else.
>> This is lovely.
>> Yeah. And that actually I that's something you see a lot in JavaScript with the with promises.
>> Yeah. Right. promises then then then then else. Your days kind of your error handling just cascades down to the bottom and >> yeah these days with async you bet you're better off without without the then then. But yeah so by the way naming naming these methods >> is really difficult. So, and then is a great example of like a method name that I have finally mostly memorized. But boy was it difficult because >> I think I think and the and is redundant there.
>> I mean, >> but >> what does it mean? Why is it why is it called and then? That's my question.
>> Yeah.
>> But then I wouldn't know what it would call it otherwise.
>> I would just call it then. But I think in C they in their async they call they have and then >> right and I think I think it comes from some some kind of functional thing. I think >> oh yeah >> it makes more sense when it's uh like a monad or something. I don't know.
>> Yeah. Oh should we should we say what cell is?
>> Yeah let's >> So cell is this is this very small language. It's quite lispy except Andy put semicolons in to make it I don't know just because otherwise it would look too much like a lisp and people would just go oh that's a lisp. Um and so it has this very simple uh type system and very s simple control flow and you can implement it in two or three or 400 lines of your favorite programming language.
>> I mean how many lines are we talking here?
>> Um I well it depends. I just like a few hundred.
>> There's but that's including the tests.
>> Uhhuh. Mhm.
>> And all the boiler plate and things.
There's more boiler plate with the rust.
I think the my JavaScript version I think is about 1,200 alto together, >> right?
>> That does slightly more >> because I did constant folding and >> minimization and and things in that. But then there are things that you get from the library that you don't get on one you know one language in the other in your >> with the rust in in our in your Python version and in my rust version all the types are just like tupless >> right >> with like known value pairs and here I used uh an enumerated type because that would be the rusty way to do things right >> right so where will I where will I see that is that somewhere in here >> so where are we where are we looking so oh here we are look >> right so This is where you're evalu tokens and then you build the a and you get a number of a nodes and here we are evaluating the a nodes. So we're walking the nodes and in uh Java JavaScript for example we've just got a big if >> and we're unpacking the tupil and the two and matching.
>> Yeah. Exactly. And the same in Python.
Yeah. I think the reason I did that in Python was mainly to reduce the lines of code in the implementation. Yes.
>> Which which is like a terrible reason for doing anything except if you're writing code to go on slides, which is what I was saying.
>> Yeah. But I think if you done it another way in even if you'd done if you done them as little classes or something, you you you wouldn't have it wouldn't have gained you anything >> cuz you wouldn't have you wouldn't have gained any kind of type safety, right?
>> Yeah. Certainly not as much as you get here. Yeah.
>> It doesn't gain you anything in those languages. But here I can I can match on on this and I know ex that I exactly have matched all my a nodes. I am evaluating all those things and I'm getting the you know they have the right number of fields. I don't just have to fish around and hope my pupil has the right number of things in and they've got names and I can and I we've got this lovely thing here where we're deconstructing those a nodes.
>> Yeah, that's great.
>> Right. We're dstructuring, sorry, not destructing, destructuring those things.
>> So, it's it's better code. It's more expressive.
>> It's easier to understand. It's easier to get right, harder to get wrong.
>> You see, I didn't I didn't quite do it for operation. So, I've got one operation that you then look inside to see what the operation is. But really, perhaps you should have >> you could have broken that out.
>> A trade-off.
Um, so this feels a little bit more stinky sometimes.
>> So yeah, so the op code here is a chart.
That's what we're talking about. So then we're matching on this chart here.
>> Um, but then this is this is future proof for all the additional operations you're going to add >> the additional operations that we're going to add at some point once once we go through the RFC process.
>> Cool. Yeah. So how um what what is there a a comprehensive cell test suite that you can use to certify your cell implementation?
Well, if if you're prepared to to say that the chess you wrote originally are the are the certification standard, then yeah, we can we can do that. They are incomplete. I have had to uh have to >> Oh, well that is >> Yeah. Oh, yes.
>> It's interesting actually this implementing it in Rust with that stronger type >> ch reveal shortcomings in the other implementations.
>> Yeah. which isn't at all surprising to me. I um I mean obviously it's not surprising anyway, but I not that long ago I implemented um a thing called I don't know uh which is a a joke um IP. It's a representation of IP addresses in a way that humans can't.
>> Yes. Yes. This is Jim's thing. Jim H thing. Uh and uh so I implemented that in Rust and I I was using a Python implementation partially as a reference.
I found all kinds of problems with that Python implementation.
>> Yeah.
>> Um for similar reasons, >> especially when you're you're returning those results and and you have to account for all the cases, >> you know, you say, "Oh, oh, oh, there there could be an error here.
Oh, I think my JavaScript implementation would have caught that because somehow an exception would have come out here.
>> Yeah.
>> And been caught over there. But actually here it's explicit.
The error condition is made explicit in the code >> because it won't compile. Right. So you have to manage it at that point which means you can give better error messages.
>> Yes. Right.
>> In the >> And how are your messages? Are they are they any good?
>> Well, they are they they attempt to be um you know uh to align with the with the Python reference obviously.
>> Right. Right. Oh dear. Then they're not very good.
Right. So look, it's working.
>> Yeah.
>> Do you have a favorite cell program that we can implement to >> I do love your bank account example.
>> Oh, that's evil, isn't it? Yeah. Let's do that.
>> It is. It is. And this is copied straight from um structure and interpretation of computer programs.
>> Yes. But this I think because you know when you I saw you first do that talk and when I did my talk based on um on you know on cell it looks really simple because you can explain it very very easily. You say look just let these things out and do this. But here we've got like lexical you got capture lexical captures and functions returning functions and when you call the function with your you know the deposit there you're calling a function that returns a function that you immediately invoke with another thing and it returns another function oh this is fantastic >> it really is it's like >> it's like okay I can see it's actually holding the balance where where is >> where is Yeah, >> where is that data?
>> So the um viewer may not have seen I was pasting that all very quickly. So I pasted the program in which we'll maybe look at in a second.
>> Yeah, it's printing out the intermediate results which is why you're getting this. This is the the a basically with the function with the method name.
>> But what we can see is attached to it.
>> We set we set the balance to what did we do? We >> we we created an account. We deposited 1075 and then we withdrew 75 >> and then we asked for the balance. And when we asked for the balance, we got out 9.5, which is the correct answer for that thing. Yeah.
>> So it does work. It somehow in this act one somehow is storing the balance inside it. And >> yeah, it's it's capturing it in that in Yes, it's capturing it in that variable there.
>> Yeah, it's this file here.
and and variables in cell are immutable except in special circumstances which is that set call.
>> Yeah. Which is of course this is copied straight from lisp as well. It's all it's all >> so yeah. So what this is is account open account >> is >> a >> a function.
>> Is it a function? This doesn't have a >> it's a fun yes it's a function >> with no arguments >> that that a function that takes no arguments >> that returns >> which within it contains a function which it immediately invokes that's what those two the parentheses are >> so and the the return value of that function is another function >> which is all that >> yes a curly bracket means start a function captures that balance.
>> Yeah.
>> So curly bracket means start a function.
Close curly bracket means that's the end of your function. If you have this colon bracket thing that means the function takes an argument or multiple >> takes an argument.
>> So yeah this is a function that takes no arguments that we return. So that's why we can call open account because the thing that gets returned the thing that open account is is a function >> and then as you said fun uh open account creates a function which is this whole thing and immediately calls it. The reason it does though is because that captures bound >> capture. Yeah. Um old timey JavaScript programmers might recognize this. This used to be quite a common pattern in JavaScript until JavaScript got better.
But the you would use immediately invoked function expressions >> to capture and hold data private.
>> Yeah. That the main purpose there is exist >> and it's inex but it's inaccessible.
>> Yeah. outside of the scope.
>> Yeah. That was the in JavaScript it was to keep things private. Whereas in in in Cell it's mostly to make things that you can hold on to at all.
>> Yes. Make objects.
>> Yeah. Yeah. Yeah. So what we've got is we've now got a function that's been that's been called and and in the thing that that function called thing holds this bowel inside it >> and it yeah but what you actually get back when you call the function is this thing >> which is another function >> which is another function which takes a method name and then so now now you can call that method call that function sorry which was returned from open account and you can pass in a method like deposit or draw >> method name which returns a function.
>> So method >> in method name and that returns another function which you then invoke.
>> So what yeah what meth what the this function does is it checks whether your method name was deposit and if so returns a function >> otherwise it returns >> cell like like rust returns the last expression.
>> Yes, thank you. Yeah. Or Yeah. In this case, the only expression, right? This whole if is one big expression.
>> Yes. But we've got the then expression and the else expression.
>> Yeah. And there's no return. There's no return statement. It just >> No, it's just the last thing.
>> It's just the last thing.
>> And then Yeah. So if it was deposit, then the function that gets returned is this thing which has which is itself a function which has an argument for amount.
>> And what that does is uses this magic way of changing bal.
>> Yeah. to be bal >> and if not we go into the else block and then we check again because we have we've got no switch we've just got if >> yeah of course we should write switch uh switch we probably could don't know yeah so then it checks whether the method is is withdraw and if so it returns a function which takes an amount which changes the balance by amount >> and then if you didn't supply deposit or withdraw then maybe you supplied balance in which case it doesn't return a function. It just returns your balance.
>> It returns. Yes.
>> And then this is the else part. So the slightly confusing thing of this is if is a function which takes in like a a test >> an a test and then function and an else function and it evaluates >> sorry an else expression a then expression and an else expression and it evaluates one or the other.
>> I think these are yeah no you're right.
They are they are expressions but in every case that is useful they end up being >> we've got them here we've got them as a function. Yeah >> I mean I think they have to be a function right like if will always call one of them so they have to be functions.
>> I oh I think that's right. Yeah >> I think anyway. Yeah. So this is this is very confusing because it looks like >> this is just like the then clause of normal if but this is not a normal if.
If is just a function. if is a function >> that takes in functions as arguments and calls one or the other based on that first thing. And once you get used to this, you're like, why is any other language not like this?
>> That's right. Well, this is continuation passing, isn't it? This is this is straight out of uh straight out scheme uh as programming as a um Oh my god, I blanked on the name because I'm nearly 56.
Um, >> it'll it'll come back to he's a big he's a big man in scheme.
>> Um, Susman.
>> No, no, no, no. Worked on Java as well.
>> Oh. Um, yeah. I don't know.
>> You know, I mean, it'll it'll anyway.
>> Okay. So, anyway, so this is just a horrifically complicated cell program.
>> Yes. Yes, it is. But it's incredible.
But we just going on one little >> and we just demonstrated that your implementation does indeed execute that code correctly.
>> Yeah.
>> Plus all the tests pass.
>> Yep. So I declare this an official implementation of cell and there are now three uh no I won't say independent implementations there are only two independent implementers but there are three implementations of cell now >> but I did I tried not I didn't when I did the javascript I didn't refer to your python implementation at all I just took the tests and uh obviously just basically took out the colons and put in more curly bracket ETS and it you know and then implemented the tests and I did something very similar here. I tried >> right >> because in also in for my JavaScript one I'd done that with um basically with uh pull iterators. So I've done it with async iterators.
>> Mhm.
>> So it's it's pulling uh but obviously I've written here I like working with iterators and ranges and things. It's a very natural way to work I think.
>> But obviously these these are iterators not async iterators. So you're not yielding in the same way you're it's you're pushing rather than pulling. Does that make sense?
>> Yes.
>> And then the only bit I had to kind of bodgege was to inside out for the ripple.
>> Right.
>> So what I'm trying to do then is I've created a little ripple which >> which stands for >> uh read evaluate print loop.
>> Mhm.
>> Which it which we'll come back to I think. Um, so I'm trying to So that implements an iterator, but every time it runs out of things, then it reads a line from the console.
>> Nice.
>> So I've kind of I've I've in that's how I'm getting the the ripple to work.
>> And so let's So I think this is going to be a separate video. This is where this is going to work, right? So we're going to have a little chat about this, >> then we're going to cut and then we're going to do a separate video. But we But it won't seem any different to you.
You'll just carry on talking. But I will chop the >> just carry on burbling on. Okay. So, so I think I'd like to ask you like what things did you like or not like about Rust while you did this?
>> Um, that's interesting. It's interesting working with because sometimes when you what if I was to go and work in Haskell, right, or in Closure or something, I'm expecting a different programming experience.
>> Mhm.
>> Because I know those languages are different. It's front and center of what they're doing.
>> Right. Right.
Whereas Rust just says I am a systems programming language, >> right? It doesn't tell you that actually secretly stuff in it, >> right? And I've worked with system programming languages for however long it is now, 35 years. So you come and just think, oh, this is systems programming language and actually it's really quite different and it's different like in ways you don't expect.
So you as you look through here, there's not really a great deal of kind of lifetime qualifier.
>> No. I've noticed >> and often you you think about, you know, that's one of the things you think you're going to have to deal with with Rust lifetime qualifiers. And I'm starting to wonder if that is based on a tiny sample of my own, right?
But actually for a lot of programs, the lifetime specifiers are not important.
>> Mhm.
>> And not a thing you encounter. And maybe like in C++ with the more kind of advanced template concepts.
Okay, that was that's an term, but even like concepts or parameter packs or something like that, right?
>> I know what they are.
>> Mhm.
>> But I'm very unlikely to encounter them in a code I'm writing because they're something more for library implementers to worry about. So I wonder if perhaps a lifetime is something that the library implements to worry about. And there was a time when I was I thought I was going to have to specify everything with a lifetime and it was all getting very stressful and actually I was just doing it wrong.
>> Mhm.
>> What were you doing wrong? All went away.
>> Oh, I was again I was trying to capture a trait. So I was trying to capture something. I was getting into the dine box.
Okay. Okay. And actually you wanted to just have it have it again have it just a generic type.
>> Yes. Right. Yes. Yeah. So there's so there's that. Um the there were things that I would naturally do that would seem quite natural to me in in some I don't know in C++ for example where perhaps I am holding I have a class an object which is holding one value and I have a another member of that object which is let's say the iterate let's say I'm holding string and then I've got another value which is the iterator over the string.
>> Self-referential objects. So, >> really hard. Really hard. Probably doing it wrong if if that's what you're trying to do in Rust. Really doesn't like >> I mean that's specifically the thing that Rust is really bad at.
>> Yeah.
>> Yes.
So, you if you find yourself heading in that direction, you probably want to come in you you want to go in a different direction. You want to back out of that and and go somewhere else.
So it was that that that was interesting that it looks like presents as uh a systems programming language but there are it's not you know and you can read the code and it all make you know you can look at somebody else's rust and you can read it and it all seems pretty reasonable >> but there are the it's idioms are really quite different.
>> Yeah. Yeah. Yeah. Yeah, it's when you're fighting the compiler that you find out, isn't it? If you're reading someone else's code, >> it's mostly fine. But when you're trying to do something that seems totally reasonable to you and the compiler's like, "Nope, can't do that." And and often often the error messages are very good and they will suggest a way out, but what they should really be saying is actually you don't want to be doing start from here. Yeah.
>> You you can fix this by Yeah. Yeah.
Exactly. You can fix this by doing but maybe you want to go over there.
>> Yeah. Yeah. Which is much harder of course for the compiler to figure out but yeah.
>> Yes.
>> So a little bit of backstory on self-reerential objects. Um in order to do async they discovered that they needed self-referential objects which were kind basically illegal in Rust. The reason you need them is because you when you when you're doing async, you pause uh in the middle of a function what looks to the user to the you know to the coder like a function but is actually more like a a strct.
Right.
>> Right.
>> Um with different states it can or enum an enum really because it's different states it can be in depending which part of the function you pause that.
>> Um >> right. Yes. And so and then that enum is going to contain stuff >> um like the local variables or whatever that are currently being been kind of because your your functions been kind of paused. So we have to store all of that state in this thing and those things need to be able to be self- refferential for reasons I can't fully remember right now.
>> This is of this isn't this Yeah. This is related to like how you often implement co- routines and things as well. Your yield points right?
>> Yeah it's exactly that.
the little Yeah, but actually that's broken out into this little function and then that little function and that >> exactly that's exactly what I'm trying to scramble to say. And the point is they discovered they needed those things to be able to be self-referential, those kind of intermediate states. And so they invented this thing called PIN, which everyone hates, no one understands, me included. Um, but the the like the key meaning of PIN is that you can have objects which are guaranteed not to get moved. Most of the time, most things in Rust could move at any time.
>> Ah, right.
>> And so you can't have self-referential.
You can't have a pointer to something within yourself because it will become invalid as soon as you move.
>> As soon as that moves, right? Yes.
>> So, so they they retrofitted the ability to say this thing will never move and therefore I'm allowed a self-referential thing.
Um, but they didn't really make it available to the normal programmer. And I recently read a blog post about how you would make that actually available to the general programmer, not just through this um async world, but generally and boy did I get lost reading that blog post. It was very very interesting. But yeah.
>> Yeah, >> there's some really interesting discussion around pin because pin is very uh difficult um to deal with for reasons I can't express because I still don't really understand it well enough. But what people have said, who I think I trust, is that if we if we could start back at the beginning, we wouldn't have pin. We would have a trait called move, which says you're allowed to move this subject, >> right?
>> And that would be an auto trait like send, which means you everything is automatically move unless you say it's not move.
>> Yeah.
And then you could you could say something is not moved and therefore have it be self-reerential if you say it's not you're not allowed to move it.
>> Right. See cuz I was I was wondering if you needed it as I didn't think about this very hard. Um, what I was kind of looking for was an a way a way to express that you've got these two members and either the lifetime of this one will is guaranteed to be, you know, I was think >> I know it does feel like the same lifetime.
>> Yes, >> it feels but it's but now that you said it's not to do it's actually >> not really to do with lifetimes. It's about to do with about to do with identity and location, right?
>> Yeah. It's about point of validity or something. Yeah.
>> Yeah. Yeah.
>> Yeah.
>> So that's that's actually a different >> Yeah.
>> different different thing that you're actually having to solve for. So >> yeah, the lifetime of it is actually straightforward, isn't it? Yeah. It's just like Yeah.
>> Just want it to be the lifetime of this thing here.
>> Yeah.
>> Yeah. Yeah.
>> Yeah.
So I had I but but in in my particular case here I solved that by saying well I'll just start with the iterator.
>> Right. Yeah. Yeah.
>> I just start then then you you've hoisted that whole problem out and it just goes for me. It went away.
>> Right. Right. Right. Well yeah. So the the really interesting thing about stuff like the move trait and stuff is whether the very very clever people doing this can figure out a way of adding that without breaking Rust's backward compatibility guarantees.
>> Oh wow. because they have really strong guarantees about if you compile new Rust code against old Rust code. What is it?
What's the guarantee?
Um there's some things that you can change in Rust editions and there's some things that you can't. And in particular, old code must still work correctly in the new compiler.
>> Okay.
>> Um which is fascinating.
Yeah, >> quite tricky I guess.
>> Very tricky. So yeah, the so even though Rust has this additions thing every 3 years, there are some constraints on what you can do there, >> right?
>> Um which are very cool constraints cuz they make it make things better, but they do mean you can't just change your mind about stuff.
All right, enough crazy uh internals of Rust talk.
>> So anyway, I I so you know I have good time. Will you and will you use Rust again?
Uh yes, why not? Um I I don't know what for as I sit here right now. So um and there's no opportunity to use it at work for example where I am at the moment >> and as I mean as you mentioned if you were doing like uh a talk or something you you'd go for the code the the language which is going to give you most bang for your buck on the slide.
>> Yeah.
>> Which is not Rust's forte. I I actually I actually have a good proof of that because I did do a talk about maths and some different bits of maths which you might remember and I started out coding that stuff in Rust cuz I just was still get I was getting into Rust. I was loving it >> and I rapidly backed away from it because my slides were just >> like like half a page of diagonal brackets and I ended up using >> type one.
>> Yes. Yeah. which and and one of the one of the things I I started using JavaScript for slides a long time ago because everybody can read it.
>> Yeah.
>> I used to use Java.
>> Yeah. For the same reason >> because just cuz everybody can read it, right? And it's so that's >> Anyway, so yeah, I I had a good time and I will write some more Rust >> I don't I don't know what >> as of this moment.
>> Maybe to write all the software tools in Rust.
>> Well, maybe. But I'm still quite still very fresh in my mind that >> so tell us about the software tools in Pascal and then we'll finish this video.
>> It's okay. So software tools in Pascal is it's not the only book on programming that you need but it's a contender right it's really really good. So it's a book that uh Brian Kennegan and PJ Pluggger wrote in the mid70s as um and it basically describes um it it describes the implementation of a number of what they call software tools which are basically what we would now call Unix utilities.
>> Right. Right. Right.
>> But at the time people didn't call them that because they were only like 10 Unix installations and they were all AT&T.
Um, but it's a it's a ped it's a pedagogical test. So it's about teaching programming.
>> Mhm.
>> And all the things that we think about as like good software practice they talk about there. They talk about like breaking things down into smaller things, unit testability, composing programs from, you know, separation of concerns and all that kind of thing. And you start off with this in this first chapter. just like tiny things like um basically WC >> you just start doing like characters >> and then you then you then you count lines >> and then oh no then you count words cuz you just break on spaces and then you count lines and then you and then it you know then in the next program you do a bit of file handling and then you >> and they just get progressively more complex. There's a bit there's a sort program that you do in the middle, right?
>> And then you go, well, you know, they're operating on the latest and greatest hardware. What if you need to sort something that's more than 16 kilobits, right?
So you so you spill to disc. So you write a sort that will spill to disc.
>> Right. Right. Right. Right.
>> And and you then you then you uh rebuild your sorder from intermediate files.
Right. And that's and it's great fun to do. That's cool. Really good.
Um, and then because it's a Brian Kernigan book, you do basically uh a version of um, uh, Enroth in the middle. You do a little type setting.
>> What's Enro?
>> It's a type setter.
>> Okay. Okay.
>> Trough. Trough.
>> Oh, I've heard of truff, right? Yeah.
Yeah.
>> Yeah. Enough is is the the kind of the >> I don't really know what trough is, but Yeah. So it's it's it's a type setting language for doing um uh you know properly nicely laid out documents.
If it if it wasn't so obscure now, if it wasn't quite so hard, it you would be everyone would be using instead of latte, right? It's a it's a print quality type setter. And it's that's the reason that L um Unix was developed in the first place was the type setting.
>> Okay. Okay.
>> That was that was the excuse. And so you have you know you it's a markup language effectively.
>> Mhm.
So you say this is my page header and this is my page footer and and then the program takes care of you know left and right justification and page numbers and >> lovely >> and then the uh I've forgotten uh the last one is a version of ED standard editor >> and I had such a good time working on that. And like I've I've been using VI since like VI, excuse me, since what >> 199 four maybe. And I learned I learned things about VI.
>> Yeah.
>> By implementing ED.
>> Yeah. Right.
>> Right.
>> And and and so it's just fantastic. And I spent about I I worked on this for like So anyway, I rewrote all the programs in in software tools in Pascal in C++.
>> I didn't I didn't translate the Pascal.
>> Yeah.
>> I wrote because they they give like a little man page of each thing and they didn't describe it very exactly. So it's like you said, it's fun to implement stuff that when you know what it's supposed to do, right?
>> Yeah.
>> And so I just I did these things and I and I worked through and I did them all kind of very TBD and I worked through and I it took me about five years because I wasn't like hammering tongs on. But I just had a really really brilliant time.
>> Um, >> yeah, it was great. Um, >> and you wrote some blog posts about it, right? So people can >> Oh, loads.
>> Look it up.
>> If I remember, I'll put a link to if I forget, remind me. I'll add a link to the their blog and yeah, >> your master.
>> So, I would I I'm not suggesting that everybody should go and do that, but it's it's really nice. There are some, you know, there are some very small programs, there are some quite large programs. There's a bit in the middle where you implement a regular expression library, right?
>> Wow.
>> And that was fascinating. M >> really just to really get into how reaxes work and it's not not a particularly sophisticated reax like but you can start to see how it could become fearsomely complex but also how you might >> optimize things how you might >> you know because you know you can get these hideous performance regression right >> so that was fascinating really fascinating I really enjoyed that.
>> So, I'm I'm on a campaign to get you to to write software tools in Rust, but it sounds like maybe not yet. Maybe you need a rest.
>> Okay.
>> Well, maybe, but maybe I wouldn't do every single one. Maybe I would I would kind of jump ahead.
>> Should we just reimplement Vim?
>> Should we just go for that?
>> See, I no I I did get into after I read because obviously VI comes from so Ed's the original Unix editor. Mhm.
>> And X is the extended editor.
>> Mhm.
>> And VI is the visual mode for X. Right.
>> Mhm.
>> So, I did get into a bit of an idea about maybe I can put a screen editor on top of my ED implementation.
>> Mhm. Mhm.
>> And may and I did think about, well, maybe I can do that in Rust and just drive ED through the >> Okay. through the command line, right?
>> Or just not not get into the guts of it, but just do it with the kind of, you know, the letter commands underneath, right?
>> Okay. Okay. And I read a whole load there are a whole load of of um like I e papers and things that were published in the mid70s about screen editors and things because um the thing about ed is this very you know on a on a on a screen like you have now it's these lineoriented editors don't make a lot of sense on the on the glass teletype.
>> Mhm. But when you remember that actually even well into the 80s a lot of people were working on print terminals.
>> Right. Yeah. Yeah. Yeah.
>> So so the lines that they typed were still there in front of them.
>> Mhm. Mhm.
>> So maybe as you were writing a function if you do it in ED now you know if you're doing it in a line editor now you you've kind of perhaps you've lost the con on the screen you've lost the context but on your on your fanfold printer >> right it's just there. It's Oh, it's just there.
>> It's just Oh, yeah. Oh, I do need to fix it. Okay, that's >> I keep thinking like like it's a it's a lifetime job, but I would really like to just reimplement Vim completely in Rust.
Well, you know, um there are there are people at Canonicle who'd be delighted to hear from you, Andy, >> but I would do it under a decent license instead of the whole like license washing.
>> Okay. Well, let's not let's not get into that. I mean, I agree with you, but that's >> it would be it would be fascinating.
>> It would be a lot of fun.
>> It is really interesting to >> lot of wrinkles. A lot of nasty wrinkles, but yeah.
>> Yeah. Um, speaking of reimplementing things from scratch, uh, I did actually upload a video on my channel last week um, of me re-implementing Town Crier from scratch in Rust.
>> And um, I did a bit of it on on stream.
I then threw away a video where I just struggled and struggled to understand how to use the Ginger templating system, which I'm never going to upload because it's just me going, I don't understand how this works for like an for like two hours.
Um, but I I got through that. Um, and I'm nearly there with I think it being good enough for us to use on our project at work. So I because I've been basically I've been barely sleeping and instead just really enjoying doing this thing which is really not there's not a lot of it and it's not clever, but I just really like implementing things that I already know how they're supposed to work.
>> Yes. Yeah. There is there is a certain there's a certain comfort.
>> Yeah.
>> In in that comes from that particularly for >> for something you're trying to do to relax, right?
>> Yeah. There's, you know, programming for money is great and everything on account of the money, >> but programming is like your, you know, you can like there's a just this like multi-dimensional space that you can navigate when you're programming, right?
>> Yeah.
And as you write the program, you're changing the landscape around you. And then as you think of new things, you're changing the land. And if that's totally open-ended, that's actually really exhausting.
>> Yeah. Yeah.
>> But if you've got a goal that you're working towards, it re it still there are still all these this space you can explore, but you've constrained that space.
>> And constraints. Yeah, constraints are really comforting, aren't they? And that's why TDD is so much fun.
Test-driven development. And actually for this project I um I I I set up a test framework so that I could build a little example and then run the actual town cryer program against that example and then use that as a reference when I then ran my program.
>> I I was astonished to read genuinely astonished to read this week. So you were talking about these these rusty implementations of of the Unix utilities >> and obviously for those things if you're replacing a tool that's been around forever you've got to be bug forbug >> mhm >> compatible >> and so the Rust implementations didn't have any >> you know memory problems and buffer overflows and all that kind of things.
They did have all kinds of file system race conditions which are a little bit awkward, >> right?
>> But I was astonished to learn that they hadn't until recently been running the test suites from the original tools.
>> That's a surprise versions.
>> Yeah, that is a surprise.
>> I I I'm sure that's what I read. I'm sure that's what I read. I was like, "No, that's that's that's where I'd start." Yeah, that's literally the first thing I did with town with the town cryer thing >> um is set up a whole a whole framework which I did I didn't put on the video because it was too boring of me writing horrific bash that runs the original town crier in Python and then ch >> and and then you compare your output because that's what you're iterating towards. Yeah.
>> And I loved I loved the the constraint of that.
>> I'm sure that's what I saw and I was genuinely astonished that wasn't >> wasn't the case. I mean, I guess not everyone would see that as fun. So maybe when when these projects started out, I think they were a bit of fun.
>> But this is not for fun. This is this this, you know, this code expressly not for fun, right? This is work.
>> Now it's not for fun. But when it was started out, I bet you that project was done for fun.
>> Yeah, maybe. Okay. Well, >> anyway, that's my idea of fun. So like people should definitely employ me.
>> Yes. So me if I'm misrepresenting the people who worked on that, I I apologize to them. I but I'm that's vital.
>> Yeah. Well, I mean you're you are a veteran, Jez.
>> Thank you.
>> And you've learned a lot along the way.
>> I mean, you were using VI in the 90s.
>> Yes. Uh on a on a scox.
>> Oh, that's unlucky. I um I I didn't start using Vim until surprisingly late in my career. I had been using Microsoft Visual Studio, not VS Code, the real Visual Studio. And and I've been using uh Jedit or JEedit for all of my non C++ work for years.
And I was really into Jedit. I loved it.
It had the this brilliant multifile search and replace functionality that I've never seen a good replacement.
never used it.
>> And then I started using Vim for my Python because it was just fun.
And what really got me into it was my writing pros was suddenly fun because it felt like coding >> and then and then I just use it more and more.
>> I do write I Yeah, I write all my pros in a in a text editor rather than a word processor. I've never >> Yeah, this is better.
Anyway, do that thing where your your friends and family ask you for help with Word and you go, "No, >> I don't know what >> no I don't know. I don't know."
>> What I would do is write it in Asky do and then run it through this program and they go >> and I don't know what you're talking about. So, it's safe. Anyway, >> all right. Anyway, so um thanks a lot, Jess. Well, we're going to we're going to end this video and then you and I are going to carry straight on with the next video, but we'll say goodbye for now.
Hope you enjoyed.
>> Okay.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
Re: 🗣️📍theprophedu📍2026 GST 103 CLASS (E-EXAM REVISION)
theprophedu
636 views•2026-06-04
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Instagram accounts got PWNed
EricParker
13K views•2026-06-03











