245 lines
22 KiB
Plaintext
245 lines
22 KiB
Plaintext
|
|
Episode: 3426
|
||
|
|
Title: HPR3426: Rust 101: Episode 0 - What in Tarnishing?
|
||
|
|
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr3426/hpr3426.mp3
|
||
|
|
Transcribed: 2025-10-24 23:11:08
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
This is Hacker Public Radio Episode 3426 for Mundy, the 20th of September 2021.
|
||
|
|
Today's show is entitled, Rust 101, Episode 01 in Tarnishing,
|
||
|
|
and is part of the series programming 101 it is hosted by Black Colonel,
|
||
|
|
and is about 22 minutes long and carries a clean flag.
|
||
|
|
The summary is, Black Colonel teaches you what rust is and how it is different from Python or C.
|
||
|
|
This episode of HBR is brought to you by an Honesthost.com.
|
||
|
|
Get 15% discount on all shared hosting with the offer code HBR15.
|
||
|
|
That's HBR15.
|
||
|
|
Better web hosting that's Honest and Fair at An Honesthost.com.
|
||
|
|
Hello and welcome to Hacker Public Radio. My name is Black Colonel,
|
||
|
|
and this is going to be Episode 01 of my Rust 101 series.
|
||
|
|
This is inspired by something that I heard Ken and Dave say on the July
|
||
|
|
July Community News episode about having they wish somebody would do a Hello World program type
|
||
|
|
thing or an introductory series on Rust, and so that's kind of what I'm going to be trying to do.
|
||
|
|
But this isn't really going to have a Rust Hello World program and at least not this episode.
|
||
|
|
That's what we're going to be doing next episode.
|
||
|
|
In this episode, I just kind of want to go over what Rust is and the reasons why someone
|
||
|
|
want to use it over Python or over C. Now I do want to say, first of all, that Rust is the language
|
||
|
|
that I use most. I use it when I want to do something that is compiled. I'll get into what that
|
||
|
|
means when I compare it to Python, and it's what I use when I want to explain something to someone
|
||
|
|
because it is very easy to see what the computer is doing by reading well-formatted Rust code.
|
||
|
|
But anyway, let's just start out with what Rust is. Rust is a, what they call a multi-paradime
|
||
|
|
programming language, which basically just means it tries to do a lot of things. But the three,
|
||
|
|
four-ish things, four or five things that I would say that they really define what Rust is.
|
||
|
|
The first one and kind of like the thing that's plastered over a bunch of its
|
||
|
|
models and what not is, it's stance on garbage collection. Now, a lot of people in Rust will say
|
||
|
|
that Rust doesn't have garbage collection. Now, strictly speaking, that's not entirely true.
|
||
|
|
It does not have a lazy garbage collection. It has what it's called resource acquisition
|
||
|
|
is initialization type of garbage collection. What that basically means is that things
|
||
|
|
memory gets allocated by the computer when a variable comes into scope, and it gets
|
||
|
|
deallocated when the variable leaves scope, which is a very efficient way of handling memory.
|
||
|
|
A lot of programming languages don't do this. A lot of programming languages just keep everything
|
||
|
|
in scope all the way through. You get stuff like globals and stuff with that sort of mentality,
|
||
|
|
like global mutables, which are not actually allowed in Rust unless you put unsafe tags
|
||
|
|
around it, which I'll get into more later. But essentially, memory is very, very, very,
|
||
|
|
very well kept track of in Rust. You will not cause memory leaks unless you know you are causing
|
||
|
|
memory leaks, unless you're writing your entire thing in unsafe tags, which I'll get to later,
|
||
|
|
and it is not recommended. The next kind of main pillar of Rust is strict typing with type
|
||
|
|
inference. Now, this is something that if you're familiar with C, you should know a little bit about
|
||
|
|
strict typing, whereas every time you define a variable, you have to put the variable type right
|
||
|
|
before what the variable name is. So let int 5 or whatever, like 5fiv equals the number 5.
|
||
|
|
Terrible example, since I just mixed my let like, I mean, if you're going to hard code a literal
|
||
|
|
into it, you could do worse, but you know, it's not the best example of a thing like, let's say,
|
||
|
|
I don't know, let char array penguin equal gen 2 or whatever. That's an example I'm going to be
|
||
|
|
using later in Rust, but where you have that char array or that int type, you need to have that
|
||
|
|
in C every single time. With Rust, it always has a type, it's still strictly typed, but it can infer
|
||
|
|
it from whatever you're supplying as of the value. So for example, if you have, you can write either
|
||
|
|
let and then the variable name, so penguin one, and then you can put a colon and then whatever
|
||
|
|
the type is. So a, if you're going to do like a literal quoted string, it's going to be of type
|
||
|
|
ampersand, Sierra, tango, Romeo, STR, and that equals, let's say, gen 2, and then semicolon.
|
||
|
|
What that'll do is it'll create a variable with type ampersand, STR, and set that equal to the
|
||
|
|
value of gen 2. But you can also just write let penguin 2 equal quote, gen 2 and quote, and that's it
|
||
|
|
without the, the type. And it, because it knows that the type of gen 2 in quotes like that, that
|
||
|
|
string value that knows that it has type ampersand, STR, it automatically gives that type to the
|
||
|
|
variable that you assign to it. And this is really useful because it's, it keeps the, it keeps you
|
||
|
|
from making errors where you start mixing your types around, like can happen in C++ and Python
|
||
|
|
and, and stuff. But it also prevents, but it also allows you to write less code because you don't
|
||
|
|
have to always be writing the what type it is as long as you can keep track of it. You can write
|
||
|
|
it, which will help, might help you sort of visually see what type things are supposed to be.
|
||
|
|
And it also helps you in troubleshooting because you can just like if something's not working
|
||
|
|
because it's saying that there's some kind of Mitch match type, you can explicitly cast a variable
|
||
|
|
as that type that you want it to be and see what the compiler says is the problem. And then you'll
|
||
|
|
know how to modify what you're doing in order to make it the type that you want. And a lot of times
|
||
|
|
will actually tell you in the compiler ways that you can fix that problem with typing. So that makes
|
||
|
|
the compiler happy, it makes computer happy and it makes you happy because it makes you have to do
|
||
|
|
less work when actually troubleshooting. I'm going to put examples of the code in the show notes
|
||
|
|
by the way for some of the things that I'm talking about. The next one that I'm talking about is
|
||
|
|
reference pointers, which going back to the way that memory works where it comes in and out of
|
||
|
|
scope. There is kind of a problem where if you have a function and you take a variable into that
|
||
|
|
function, then that variable is going to be taken into the scope of that function. So when that
|
||
|
|
function ends, then that variable should be deallocated and destroyed. But if you use it later in
|
||
|
|
the main function, then the compiler is no video what to do because it doesn't have the the actual
|
||
|
|
value there. But the thing gets around that is with that ampersand operator on the type, which
|
||
|
|
borrows that value to a subroutine or to a function and then destroys the reference without
|
||
|
|
the actual value. This is basically like the way that pointers work a lot of times in C,
|
||
|
|
but it's a lot more elegant in the way that it's formulated and you're not actually having to
|
||
|
|
declare an actual raw pointer value in order to do this. You can also dereference something that
|
||
|
|
you want to be owned using the asterisk symbol, which is the the star symbol, which is the way that
|
||
|
|
you would declare a pointer traditionally in C. So the the fourth sort of pillar of rust is the
|
||
|
|
idea of being immutable by default. So when you declare a variable like let's say let minum equal
|
||
|
|
two, then it's going to automatically, you know, do the type inference of, you know, whatever the
|
||
|
|
heck this needs to be is the type that it's going to be. And let's say you want to add one to that
|
||
|
|
now you can do minum equals minum plus one, but that won't actually work because you didn't
|
||
|
|
declare that minum was going to be changed. So when you actually set up the variable, the way
|
||
|
|
you would do that correctly is that you would put let mute MUT mic uniform tango minum equal two,
|
||
|
|
and then you can do minum equals minum plus one, then you can print it out and it will give you the
|
||
|
|
value it will give you three out in that case. And the reason that it does that is because if you
|
||
|
|
keep things from being changed at runtime, then you can guarantee the awareness of what the memory
|
||
|
|
is. So it keeps track of that this thing isn't doesn't need to be changed, which is going to limit
|
||
|
|
the errors that you can encounter in your actual binary after it's compiled because a lot of times
|
||
|
|
what can happen is that if somebody can figure out how to modify or how to make the program modify
|
||
|
|
some variable that you set that can cause a lot of bugs or even exploits, whereas if it's something
|
||
|
|
that doesn't need to be modified ever, then you can just not have it be modified ever. Just
|
||
|
|
takes the value it has when it was instantiated. And the last thing that I want to talk about as far
|
||
|
|
as like the pillars of Rust is this idea of unsafe mode. A lot of these things you really have to
|
||
|
|
work around. If you want to write like really low-level code or if there's something that you
|
||
|
|
know what you want to do like with the actual like low-level part of the computer, like if you want
|
||
|
|
to modify individual memory addresses or use raw pointers to point to specific memory addresses
|
||
|
|
or what have you. A lot of the defaults for Rust don't let you do that because it's not safe to
|
||
|
|
do in a regular program. But all you have to do is put it in essentially do unsafe and then a
|
||
|
|
curly brace and then whatever code you want it to be unsafe and then end that curly brace and
|
||
|
|
then only that part of the code will be run in what's called unsafe mode, which essentially means
|
||
|
|
you can do whatever the heck you want to do. And it assumes that if you're running that code like
|
||
|
|
that that you know what you're doing and any bugs that you introduce you can find essentially.
|
||
|
|
So it allows you to do whatever you want to do. You just need to make sure that you let it know
|
||
|
|
hey I know what I'm doing. I can do this. And my example for that is what you can actually do is
|
||
|
|
you can just write in C or you can import functions from C code directly into your Rust program using
|
||
|
|
extern command so you can do extern quote the capital letter C and quote and then curly brace
|
||
|
|
and then you can put a function declaration in the way that you would in Rust. But with the actual
|
||
|
|
value without the actual name of the function in C. So I'm using the print f example from C.
|
||
|
|
So print f takes a value that's a I mean technically it's a character array because that's what
|
||
|
|
strings are in C. But I'm using the ampersand STR type which does throw a warning on the compiler
|
||
|
|
but it can handle it. So it's mostly fine. I just don't I haven't I didn't figure out how to
|
||
|
|
actually do a character array as a rust type per say. I mean I guess I could have actually just done
|
||
|
|
whatever not the point like I actually thought of how to do it just now but it's not super important
|
||
|
|
and also I would need to give it a defined size. So I'm not going to worry about it at the moment.
|
||
|
|
The point is is that you can have this kind of like print f is a C function and you're giving it an
|
||
|
|
input from a rust type and then you could do a semicolon to end that line and then end the curly
|
||
|
|
brace and you have that extern block that extern C curly brace function declaration and curly
|
||
|
|
brace. And then in your main function you can put unsafe tags and put just unsafe open curly
|
||
|
|
brace print f hello world and parentheses semicolon and then end curly brace. And this is actually
|
||
|
|
rust syntax but you're using the function from C. So rust takes the value you gave it for the
|
||
|
|
argument. So hello world puts that into the C function of print f and runs that in unsafe mode
|
||
|
|
and just does whatever that function says to do and then it works. So this is actually a way of
|
||
|
|
writing a hello world program in C in rust which is really cool to me because it means that even
|
||
|
|
if you're familiar with here if you have colleagues that you see you can still use rust and just import
|
||
|
|
those functions into your program. Now I kind of want to talk about why I would use C or rather
|
||
|
|
why I would use rust over Python and actually a lot of the reasons why I would use rust over Python
|
||
|
|
is a lot of the same reasons why I would use it a why I would use C over Python which is that it
|
||
|
|
makes it faster because it's compiled as well as other things that kind of help with it being
|
||
|
|
compiled is that it you can get help from the compiler. So if you make an error in Python nine
|
||
|
|
times out of 10 it just doesn't even tell you what it is because it just eats that error and gives
|
||
|
|
you weird output and you have to do a bunch of print statements in order to figure out what the heck
|
||
|
|
happened and et cetera and it's just not a lot of fun. Whereas in rust when you make a mistake
|
||
|
|
it will tell you exactly what your mistake is exactly where your mistake is and suggest some
|
||
|
|
options on how you might fix that mistake sometimes. It also creates a smaller binary executable size
|
||
|
|
and this is important in a lot of situations where you want to keep things portable like if you
|
||
|
|
want to put this program on a flash drive for example if you want to put on an SD card or something
|
||
|
|
of that nature. For example I run rust programs on my phone and it's useful because then I can
|
||
|
|
compile them or cross compile them on my computer importing the rust binary that's only like a few
|
||
|
|
kilobytes or megabytes and then run it on my phone and I don't need to take up all of the the whole
|
||
|
|
code base worth of well the whole code base and then the whole runtime layer as well I don't need
|
||
|
|
to take up all of that memory on my phone which is really nice. It also creates a higher throughput
|
||
|
|
which means that because it's faster and it's a smaller size you can push more data through it
|
||
|
|
and sort of it and it will just handle it basically. It's also more logically consistent so one of
|
||
|
|
the things that I have a problem with in Python is that because nothing it has static type you can
|
||
|
|
just get really confused and really down in the weeds of what the hell is going on in your code.
|
||
|
|
It's one of the my sort of guiding principles when it comes to good programming languages is that
|
||
|
|
it shouldn't abstract away the machine like you should be able to follow what is happening in your
|
||
|
|
code very easily because your computer is pretty stupid your computer doesn't like your computer
|
||
|
|
can't make implications about like philosophy or whatever at least not yet so it shouldn't you
|
||
|
|
shouldn't require those kind of implications to read your code and so those are a lot of the reasons
|
||
|
|
why I would use it over Python why would you use it over C is because well first of all it's
|
||
|
|
safe by default so in C there's a lot of problems where you can run into with memory leakage which
|
||
|
|
I know if you write good C you're not going to worry about it and you can implement a lot of the
|
||
|
|
same best practices that rust uses by default you can implement those in C it just requires a lot
|
||
|
|
more writing of C like there's a lot it's a lot more verbose try and see which gives me to my
|
||
|
|
next point which is that it's a lot easier to read rust than it is to read C because a lot of the
|
||
|
|
syntactic sugar and the syntax that's in rust just makes more visual sense at least to me I mean
|
||
|
|
I think I think it's kind of makes more visual sense in general because it kind of follows a lot
|
||
|
|
of the same visual cues as it were as I mean I would say as Python but with Python a lot of that
|
||
|
|
actually has semantic value whereas in rust it just looks that way and you can actually rewrite it
|
||
|
|
in a different way that's in a lot of different ways like you can with C code where you can write
|
||
|
|
things as one liners with a semicoloned elimination and all that but you can also but because of the
|
||
|
|
way that the syntax of it is even when you do that the actual progression of the way that the code
|
||
|
|
is makes a lot more sense than in C because you have to deal with less pointers you have to deal with
|
||
|
|
less weird data types because C is limited with a fact that it's translating it directly into a phrase
|
||
|
|
of assembly and because it's translating it into a phrase of assembly assembly it doesn't have stuff
|
||
|
|
string this per se it uses a raise of characters it uses a raise of bytes which are translated into
|
||
|
|
ASCII characters when you push them to standard output but rust just lets you write things as strings
|
||
|
|
and then it handles all of that in the compiler all of that like computer egeargany stuff and I
|
||
|
|
like that it lets me do that because I can write it as a human but still understand it as a computer
|
||
|
|
because yes it says ampersand str but one of that thing things that that means is that it's a
|
||
|
|
str it's a string of characters so it's a string of these data bytes or whatever it is like
|
||
|
|
of letters and the ampersand actually tells me that it's actually referencing it from a place in
|
||
|
|
memory where it has this literal stored which does actually improve a lot of the ways that you can
|
||
|
|
deal with sort of your understanding of the computer aspect of now a lot of people would say that
|
||
|
|
this is a lot of these things have been solved in C++ but C++ is really dumb it's a really dumb
|
||
|
|
language and it introduces a lot of errors and a lot of memory leaks into C like it it is meant to
|
||
|
|
be more human friendly at the expense of being computer friendly that's sort of what it sort
|
||
|
|
it boils down to and that's why I don't use C++ I use C but I don't use C++ ever it's just
|
||
|
|
I've tried to do it and it's it is human friendly but when you're trying to debug or if you're
|
||
|
|
trying to actually understand what your computer is doing with the information is not at all pleasant
|
||
|
|
to do that you also can get arrays and vectors and all of that in Rust which by default aren't
|
||
|
|
there in C you would have to import libraries that in C or you would have to write it yourself a
|
||
|
|
lot of times but like the best thing about Rust in my opinion the thing that I reason why I use
|
||
|
|
it over C so much is because it has these two types called option and result and what those do
|
||
|
|
is that with option if you have a value you want to be optional you can say that it's type is
|
||
|
|
option then you can have a less than symbol and then whatever type you wanted to have normally
|
||
|
|
and then comma and then none and then a greater than symbol the left and right sort of triangle
|
||
|
|
braces what that'll do is that it will try to like if the result of whatever you're doing is like
|
||
|
|
if it can have the type that you want it to have then it will return a container called sum
|
||
|
|
and then whatever the actual value is of the type that you want it to be and then if it can't
|
||
|
|
do that if it's unable to assign it that type then it returns the type none which lets you know
|
||
|
|
that it wasn't able to do that and this makes it really easy because it's like Booleans but with
|
||
|
|
structure and that result is a sort of the same way for functions because what results will give
|
||
|
|
you is that you can get give it a certain type if it succeeds like if it would return true as it
|
||
|
|
were or return exit status is zero or you can have a return a different type if it fails so you can
|
||
|
|
have a return a different string or a different like exit code or even of something of type error which
|
||
|
|
might have more information about how the error occurred within it and so you can use these as a
|
||
|
|
really really elegant way of doing error correction and error catching in your code and it's so nice
|
||
|
|
to be able to use that because it's writing a lot of that stuff from scratch and see or Python
|
||
|
|
was one of the things that gave me a headache the most and so this just takes care of it all for you
|
||
|
|
and it's all very well integrated and very well built in I will say that one of the things that
|
||
|
|
kind of annoys me is that because everything is statically typed you can get into situations where
|
||
|
|
you get verbose where you're doing a bunch of typecasting from one type to another which can be
|
||
|
|
annoying but it's nowhere to see it's way better than see actually and it's it's compiled so you
|
||
|
|
don't have to deal with a lot of the slowness or a lot of the weirdness of Python or my preferred
|
||
|
|
scripting language is lua and I would use it over lua when I would want something to be just faster
|
||
|
|
or smaller or compiled so it's a little bit more portable so you're the person you're sending it to
|
||
|
|
doesn't need to have lua installed or it doesn't need to have that particular framework installed
|
||
|
|
because you're just sending them a binary and maybe they need to have the libraries installed
|
||
|
|
but a lot of times at least when you're running Linux you can have a lot of those dependencies
|
||
|
|
taking care for you you can use can you auto tools in order to have them in port all of that at
|
||
|
|
compile time you can package it in with whatever packaging solution you want and it will just work
|
||
|
|
you can do a lot of that with lua as well where you include the runtime in the binary but that's
|
||
|
|
just a lot larger of a file and a lot more of it to do than just including header files and stuff
|
||
|
|
like that I didn't even get into the way that modules into all of that work which is so much
|
||
|
|
better than seeing Python and oh my gosh the directory structure and Python can go die but
|
||
|
|
that those are kind of the basic points of the reasons why I like Rust and why Rust is I'm
|
||
|
|
really excited for Rust to be added into the kernel I'm kind of rambling at this point but
|
||
|
|
I'm I'm really excited for a lot of that stuff because Rust is a very good programming language
|
||
|
|
and I think everybody should at least know about it but I think everyone should really learn it
|
||
|
|
because it is just see but better it's what C++ wishes it was thank you for listening to all this
|
||
|
|
if you want to contact me I will put my contact information in the show notes and I'll talk to you
|
||
|
|
guys next time where I'll be writing a hello world program in explaining the way that hello world
|
||
|
|
programs as well as macros and probably that's about it honestly because the hello world program
|
||
|
|
in Rust is super simple I'll explain a little bit about cargo as well so explain cargo macros
|
||
|
|
and the hello world program next time on Rust 101 thank you talk to you next time
|
||
|
|
you've been listening to hecka public radio at hecka public radio dot org we are a community podcast
|
||
|
|
network that releases shows every weekday Monday through Friday today's show like all our shows
|
||
|
|
was contributed by an hbr listener like yourself if you ever thought of recording a podcast then
|
||
|
|
click on our contributing to find out how easy it really is hecka public radio was found
|
||
|
|
by the digital dog pound and the infonomicon computer club and it's part of the binary revolution
|
||
|
|
at binwreff.com if you have comments on today's show please email the host directly leave a comment
|
||
|
|
on the website or record a follow up episode yourself unless otherwise status today's show is
|
||
|
|
released on the creative comments attribution share a light 3.0 license
|