Olivia Ifrim πŸ¦€ Profile picture
Jan 23 β€’ 12 tweets β€’ 5 min read
🧡 Understanding @rustlang's newtype idiom, when and how to use it. πŸ‘‡

Let's imagine we are building a mini-database for students and professors, here is our starting point.

πŸ‘‡
The idea is very simple:
* we keep track of professors using a u32 id
* we keep track of students using a u32 id

We are using a HashMap here, but eventually, this could be a trait with a real database behind it, so the ids are quite important here as this is how we find objects
Now, we want to implement course registrations. A student can register for the course of a professor.

Here is how the database looks now.

We've added a new course_registrations vector, and we use it to register students for courses and then check if they are registered.
So far so good, let's write an example and verify our code.

In this setup we have one professor: John, and two students: Bob and Sue.

Both Bob and Sue register for John's course, because John is amazing.
Now we write some code in main to verify our registrations.

But wait, we just added both Bob and Sue to John's course, but according to this Sue is not registered for John's course πŸ€”πŸ€―
Let's zone in on the bug. πŸͺ²
The bug here is we mixed up student_id and professor_id in the implementation of is_registered. Since they are both u32, it's an honest mistake to make.

The fix is easy, we swap student_id and professor_id, but let's think bigger. Can we improve our code to avoid it altogether?
1/ Attempt 1: Add a type alias for student id and professor id
This improves the readability of our code, but if we go ahead and we make the changes in the rest of the code you'll see functionally there is still no difference.

The code still compiles when we mix StudentId with ProfessorId and we still get the wrong answer.
2/ Attempt 2: Add a new type for professor id and student id.

This syntax is a little different, but basically, we define a new struct, with one unnamed u32 field inside it. This is called a new type. One of ProfessorId, and one for StudentId.

Let's see what happens now.
Now we run the same code, but this time the compiler pinpoints our bug πŸͺ² and doesn't even allow us to run the code.

It also conveniently tells us exactly what to change.
And that was a quite long explanation of #rustlang's newtype pattern! πŸ¦€πŸŽ‰

As the pattern itself is very easy to implement, I decided to focus the thread more on the motivation and how/why it helps. Hope this was helpful!

β€’ β€’ β€’

Missing some Tweet in this thread? You can try to force a refresh
γ€€

Keep Current with Olivia Ifrim πŸ¦€

Olivia Ifrim πŸ¦€ Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @oliviff

Jan 6
🧡 Introduction to @rustlang iterators πŸ¦€ πŸ‘‡

doc.rust-lang.org/std/iter/trait…
1/ What are iterators?

Iterators are a convenient way to traverse collections. A collection contains multiple elements of the same type (think vector, hashmap, tree, etc.), i.e. it makes sense to traverse it.

This is not a Rust specific concept, see en.wikipedia.org/wiki/Iterator#…
2/ Before/After iterators

Let's look at what code looks like with or without iterators. We have a list of people (type Person), which we want to traverse.

Without iterators, this is a for loop with an index.

With iterators, this is a "range for" with an .iter() call.
Read 12 tweets
Dec 11, 2020
A 🧡 about my πŸŽΎπŸ¦€ game rewrite!

Context: I started off with ggez + specs and a very basic understanding of #rustlang and the game I wanted to make. I decided to investigate macroquad+hecs as an alternative and ended up attempting a re-write. This is a thread about my attempt!
✍️ How much did you actually rewrite vs reuse?

I started with an empty main. I asked myself how each thing was implemented before and if it still made sense. I reused some of the components I had from before but I also changed a lot. Some core ideas stayed and some changed.
⏱️ How long did it take?

Judging from the commits and dates, I think it took about 12-14 hours of development. One thing to note is that a rewrite was only possible in this time because my understanding of both rust and the task have significantly improved since I first started.
Read 8 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(