flowchart LR A(Python) --> B[fname.py file] B --> C[python fname.py] C --> D{hello world} E(Rust) --> F[fname.rs file] F --> G[rustc fname.rs] G --> H[./fname] H --> I{hello world}
Packages
Systems in Rust
Announcements
- The second homework, “Hi cargo”, is ready after this class.
- It is comically trivial.
- Mostly makes sure you have everything set up.
- Due Friday, 12 Sept. at 1440 ET.
Today
- Hybrid Day
- Build system/package manager
- Theory behind Cargo
- Trap in Cargo
- Use Cargo
Build Systems
Interpretation
- We once again address interpretation vs. compilation
- I think of this as programming vs. scripting
- We can think in terms of languages - Rust/C vs. Python/JavaScript
Scripts
- I regard a script a:
- Text file
- Which describes actions for a computer
- Readable to humans
- And readable to a program (like
python
) which can direct the computer to act
- We note that this is much closer to being a text file that it is to being a program.
Programs
- We can create programs but we also use existing programs.
- As an example, consider the Firefox web-browser
- If you use Chrome, keep that to yourself, that’s embarassing.
- This is what “Firefox.exe” looks like on a Window device.
Firefox.exe
A{Ÿ@€ÿw.·þ9ÏCñ~¿‰ó€Ë @€ÿ¶ûCþD8ßué¬% Aƒù/„î% L‹RHƒÂHƒÀM…Ò…wÿÿÿM…À„à ID$¹ÿ A·ƒú-…“ IPMHfAƒx-IDÑD·fE…À„| E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùc…P D·BfE…À„A E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùo… D·BfE…À„ E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùn…Ú D·BfE…À„Ë E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùt…Ÿ D·BfE…À„ E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùe…d D·B
fE…À„U E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùn…) D·BfE…À„ E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùt…î D·BfE…À„ß E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùp…³ D·BfE…À„¤ E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùru|D·BfE…ÀtqE·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùouID·BfE…Àt>E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùcufƒz „* ë ƒú/„i# L‹ HƒÀM…À…GýÿÿHŒ$ð è)˜ fïÀL„$ fA@ fA@fA H„$à H‰D$ HÇÁÿÿÿÿ1ÒA¹0 èE …Àˆ# L‹„$H ¹ 1Òÿû H‰ÃH…À„;# L´$@ AÇFà AÆFø LŒ$à AÇ H‰Ùº M‰ðÿõú L‰ÿ…À„4# €¼$8 …_# D‹„$ L¼$0 L‰ùL‰òè™ A€ …X# L´$ AÇFà AÆFø 1ÉL‰òA¸ ÿ0ù = t…À…! ÿù ·èÍ €…ÀNèA¼) @¶L=t˜ H‰ØHÿÀHƒør H‰Ùÿ°÷ @„ö…*" A€÷³1íH
¤ ÿ’ü H…ÀL‹d$`…6# L‹M…À„w ID$¹ÿ A·ƒú-tƒú/„»! L‹ HƒÀM…ÀuâéJ IPMHfAƒx-IDÑD·fE…ÀtÓE·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùlu«D·BfE…Àt E·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øa…jÿÿÿD·BfE…À„[ÿÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øu…%ÿÿÿD·BfE…À„ÿÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øn…àþÿÿD·BfE…À„ÑþÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øc…›þÿÿD·B
fE…À„ŒþÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øh…VþÿÿD·BfE…À„GþÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øe…þÿÿD·BfE…À„þÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€ør…Ìýÿÿfƒz …ÁýÿÿH‹H‰HøHƒÀH…ÉuðAÿͰL‹d$`ë1À„Û„Æ AÇE1ÉAöÇtyL‹M…ÀtqID$¹ÿ A·ƒú-uIIPMPfAƒx-IDÒD·fE…Àt6E·ÐA9ÊDCÁEP¿E‰ÃA€Ë A€úE¶ÓECÐA€úfuéj ƒú/„$ L‹ HƒÀM…Àu™Aö×E¶ÇAƒàHŒ$ð Hœ$ H‰Úè˜ @Šs@„ö…à# ƒ¼$ I‰ÿu1íë/H
} ÿ$ù H…À…à% H
- I would not regard that as readable to humans (depends on the human)
Compilation
- Compilation is the process that takes text-based code to whatever we saw on the last slide.
- Can be quite simple - we made
hi_world
, a program, already.- Notably it didn’t do a lot.
rustc
takes a.rs
file and makes an executable- a program, sort of
- Executables run as command with
./
prefix- This differs from
python3
which runs a script without creating a corresponding program.
- This differs from
.py vs .rs
- You only have to compile once to have the executable forever.
- Most programs are executables, not scripts.
Rustc
rustc
is rarely, if ever, used directly- Over the years (since like, 1960) code has increased in complexity.
- Many files (think pgl.py, WordleGraphics.py, EnigmaRotor.py)
- Many libraries (think NumPy, pandas, scikit)
- Complex file systems (01/rustup.md)
- Over the years (since like, 1960) code has increased in complexity.
- The solution was automation.
Build Systems
- We don’t have a real equivalence to compilation for Python.
- There is Numba
- We do have a build system equivalent.
- I use flit, which is easy.
- I think there’s others… Setuptools? Hatchling?
Flit
- Flit solves a novel problem for Python programers.
- Not: Let’s make some code that I can run.
- Instead: Let’s make code that can be used in code other people run.
Packaging
- NumPy, pandas, and things like CS 151 PGL can be “built” into packages with Flit and friends.
- Basically, instead of running e.g.
python3 mycode.py
- Run
flit init
to make a new folder, edit some code, then runflit publish
to add it topip
- Basically, instead of running e.g.
- Takeaway - package management and build systems work real well together.
Wheels
- The thing that
flit
and friends create and distribute is not a.py
file. - Rather, they are “wheels” which are not human readable.
- A lot like compiled code
- Takeaway - a good way to think of Rust is that we’re writing packages for ourselves.
Cargo
- With Python, we use
python3
(orpip
, but perhaps aspython3 -m pip
). rustc
is not really the equivalent to that:- Rather, we use
cargo
, the Rust build and package manager. cargo
will handle any usage ofrustc
that we may need.- We can easily then distribute code across multiple files.
Cargo New
Build+Package
- Cargo is Rust’s build system (like
flit
) and package manager (likepip
). - We will use Cargo instead of
rustc
for the rest of the term.- My sense is that this is the industry standard.
- We’ll step through an example, then you’ll do a (very simple) exercise.
New
- The first thing to do with Cargo, as a rule, is great a new package.
- This is kinda like creating a new
.py
file. - It is a bit more like creating a Python project from a template repository.
- This is kinda like creating a new
Do it
- To do so:
cargo
is, well, Cargonew
creates a new package.throwaway_example
is the name of the package1.
Examine
- The most natural thing is to see what has changed.
- For me, I see a new directory:
throwaway_example
- I change into the directory to examine it.
- Not much there:
Aside: Tree
- Can also see directory structure.
- Install
tree
with your preferred installer (perhapsapt
orbrew
)
- Then use
tree
instead ofls
main.rs
- Cargo creates projects with a default main file.
- The name “main” is basically mainful to Cargo - it says which, if multiple,
.rs
files to read first when trying to execute the code in a package.- Make sure you understand that sentence.
Cargo Run
Run
cargo run
is probably our closest equivalent topython3 throwaway_example.py
or the “Run” button in VS Code.- Of note, you can not simply do “new” then “run”.
- “New” creates a new folder.
- “Run” must be done from within that folder.
Try it
- Do this:
- See this:
Again!
- If you run again, the process will:
- Skip the compile step.
- Be way faster (∞x reported here)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/throwaway_example`
Hello, world!
- 0.56s -> 0.00s
It’s fast
- 0.56s -> 0.00s
- This is why we use languages which compile.
- Python took around .04s, for me.
- The results are:
- Guess how long it takes to compile
python
, by the way.
Other files
- Go ahead and add another
.rs
file and see what happens.- Add it to the
src
directory!
- Add it to the
- I’ll use this one - I change filename and text, but
Run it again…
- Nothing changes.
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/throwaway_example`
Hello, world!
- This is the same as adding another
.py
file then not usingimport
or including its code in any other way.
Swap the names.
- I use
mv
(move) to change:main.rs
toold_main.rs
secondary.rs
tomain.rs
- Things change!
Compiling throwaway_example v0.1.0 (/home/user/throwaway_example)
error[E0601]: `main` function not found in crate `throwaway_example`
--> src/main.rs:3:2
|
3 | }
| ^ consider adding a `main` function to `src/main.rs`
For more information about this error, try `rustc --explain E0601`.
error: could not compile `throwaway_example` (bin "throwaway_example") due to 1 previous error
Requirements
- You need a
main.rs
with a function namedmain
. nvim src/main.rs
-> Change “secondary” to “main” -> “cargo run”
Options
Carry-on only
- I try to live me life without baggage.
- (I don’t like
cargo
)
- (I don’t like
- Why? Well…
- I can’t name things the way I want
- I can’t add
cargo
created directories to repositories.
- Well, I can, but it I have to use options.
Option 1: Names
- It is uncommon to name a package numerically.
- It is however, I think, useful in a course.
- It is also, I think, useful to write packages for a course.
- So we do so.
Name Scheme
- I have used the following scheme this term:
- Each class day is denoted as a two digit value.
- The first digit represents the zero-indexed week.
- The second digit represents the zero-index position in
["Lecture", "Lab", "Homework"]
Today
- Today is one week from the first day of class, last week.
- Today is one day from the first day of the week, Monday.
- So I denote today
11
Use Cargo
- Let’s use
cargo
to make a package called11
.
- What happens?
Problem
Creating binary (application) `11` package
error: invalid character `1` in package name: `11`, the name cannot start with a digit
If you need a package name to not match the directory name, consider using --name flag.
If you need a binary with the name "11", use a valid package name, and set the binary name to be different from the package. This can be done by setting the binary filename to `src/bin/11.rs` or change the name in Cargo.toml with:
[[bin]]
name = "11"
path = "src/main.rs"
Solution
- We can make a folder named
11
- But not a package named
11
. - We use the
--name
flag.- I use the name of these slides, rather than the number, as the package name.
- This should be allowed.
Option 2: VCS
- It may be the case that you created a
11
folder outside of your271rs
directory.- I do this often, then plan to move it in latter.
- This can pose a problem.
Situation
git clone
a271rs
repository, e.g.:
Move
- I’d like to use the
mv
command to put11
in271
rs.- Notation is “mv” then “source” then “destination”
- I have this:
Status
- Then I
cd
into271rs
to add/commit/push
Add
- Add doesn’t work:
- By default,
cargo
initializes new projects as a git repository. - Putting a git repository inside another git repository is non-trivial.
Confirm
- You can tell by looking for the hidden
.git
folder in11
.
- You’ll see something called
.git
. - You can delete it, but this is inelegant.
Solution
- Use
cargo new
with the option to have no “version control system” used.
- You can confirm there is no hidden
.git
folder. - This can be moved into
271rs
or created within271rs
Exercise
Exercise
- New Cargo project, in
- A folder named
11
, with - A valid Cargo name (not
11
), that is - In your course repository and therefore
- Has no
cargo
managed repository, and - Present on your remote GitHub repository
- The conents of the project are immaterial.
Disambiguity
- I have seen students take extreme liberties with naming folders and assignments.
- I believe no ambiguity exists within the instructions.
- It is trivial to check the following:
- Unless you are working ahead, a file readout other than the following is wrong, and would be worth no points as it does not constitute submission of assigned work.
Fin
Footnotes
Well, kinda. We’ll get to that.↩︎