We’re aiming to build out the first few Rust exercises without digging into too much Rust-specific code. Effectively we want exercises that cover Chapter 3 of the Rust Book or other generic programming concepts and can be solved without knowing Rust-specific ideas (such as ownership).
In this forum thread, I want us to decide which existing Rust Exercises and Open Rust PRs meet this criteria. We’ll then have a forum thread for each exercise to get it over the line.
Please discuss and agree then ping me, and we’ll discuss the first one.
Where there is disagreement that cannot be resolved, ping me and I’ll try and guide the conversation!
Once this is done we’ll work through a couple of the Open PRs in threads and I’ll try and guide everyone as to what needs tweaking/improving (if anything!). This can then form the basis of knowledge for future PRs etc.
My aim is for the whole group to start building a shared knowledge and understanding of how we build exercises and a syllabus successfully :)
I’ve clarified that I mean “existing Rust Exercises” and Open Rust PRs. I’d like to focus on this for now, rather than a wider syllabus or looking at exercises from other tracks.
For functions, I believe to allow practicing writing functions, CI on rust track needs to ignore lib.rs & instead consider only exemplar.rs along with the test files.
I’ve mostly ignored existing concept exercises as I find the introduction.md to be lacking. The exemplar.rs often felt like too much at once. This is the reason why some of the PRs are implementing similar concepts for instance cars-assemble
It does sound like your idea is to completely replace some of the current exercises (or did I misunderstand)?
What do you think about implementing the logs, logs, logs! from go?
I could write that concept to help speed up the process.
@iHiD, how will this “new” process deal with reviewing written concepts, can I for example go in into a pr and leave feedback or is there some kind of system?
I want to understand where we stand first before we start building new things. We have 10 Open PRs and a wad of existing exercises.
So, my question is: Out of the existing exercises (those Dinesh posted and those in the track already, which ones cover topics in Chapter 3 of the book).
Then, once that’s clear, the next step will be to work out what’s missing (if anything) and agree where those come from (new exercises or copies). Then we can look at Chapter 4 and the more complex things etc. But I want us to get the relevant ones of the existing 10 PRs merged and in a good state before we start working on new things.
I want to just take one step clearly at a time, else we all end up talking at cross-purposes
(For example, one of the open PRs is on the “Option” concept, but that’s not part of chapter 3 (as far as I can tell), so I want to ignore it for now)
Well, I think it is easier to say which is not covered since Denish covers most of them already. And you can look at my list above for what I think chapter 3 holds. So in my opinion this is what is missing:
It was the fastest way to ignore them rather to understand since I didn’t know Rust to begin with. So as I learned Rust myself, I started implementing concept exercises that I would’ve benefitted from.
It is already implemented but it targets the enums concept. Perhaps you mean to cover the char type
As @iHiD mentioned, I would really appreciate feedback on open PRs, I will try to be prompt with responding and making updates there.
Specifically I request that hints.md, introduction.md, instructions.md be reviewed
I might have used inconsistent identifiers for concepts, for instances for-loops is supposed to be for-in, but I don’t know if there are canonical identifiers across languages.
@isDineshHere (and everyone else) I’d like us not to give feedback on those PRs yet. We will get to that next week, and get them all merged in, but I want to take one step at a time, so everyone can learn about the feedback we want on each PR, rather than lots of people giving potentially conflicting (or incorrect) advice.
(If we can all learn how to make great Concept Exercise PRs we’ll be able to increase the speed we can add new exercises and all work together to help other tracks etc. But there’s an alignment and knowledge-sharing step that needs to happen to get there. I want us to all have a very clear list of what Concept Exercises should be achieving to get them over the line. But I promise we’ll get to that soon, and get those PRs merged! :))
From my understanding this is how the 5 sub sections on Chapter 3 of the book are currently covered by open PRs and existing concept exercises.
3.1 Variables & Mutability
cars-assemble; does a bit of explainer of assignments in introduction.md as well as how to define a mutable variable. I don’t believe its enough to cover the section from the book
@iHiD Here is my answer to your question. I mostly agree with Carl, but am more conservative: fewer PRs made it. Reasoning about the deviations at the bottom. The green ones are definitely covered by Chapter 3.
I disqualified #1669 High School Sweethearts because it seems the Book (at all) does not cover formatting strings to the extent that is required by the exercise.
I disqualified #1673 Log Levels because it deals with strings, whose Rust-peculiarity (subject of Chapter 4) is part of the exercise.
#1676 Phone Number Analysis deals only with String specific methods, which might be fine: a normal documentation search problem.
Apologies for the late reply, I have to fix my email notifications from the forum.
I think my list pretty much matches @MatthijsBlom and @isDineshHere . I would include Phone Number Analysis, because it states to deal with tuples, which are covered by chapter 3. I think @isDineshHere did not mention the existing assembly-line, which also fits the criteria (although the examplar uses match, which would not be appropriate at that point).
Side notes:
The log-levels PR is confusing to me, because the task seems to be exactly the same as the existing (non-concept) exercise semi-structured-logs.
The existing exercise low-power-embedded-game wants to teach tuples (part of chapter 3), but has structs as prerequisite. So that exercise probably won’t fit in the plan of modelling the syllabus after the Rust book.
Including the existing exercises and excluding everything that didn’t make the cut, I’m trying to answer this question as concisely as possible:
Out of the existing exercises (those Dinesh posted and those in the track already, which ones cover topics in Chapter 3 of the book).
So let’s get these ones into a good shape. Firstly, I want to start with a very clear pathway:
Every exercise has an examplar.rs. This should be the minimum to solve the exercise using the concepts learnt so far. It doesn’t have to be idiomatic. It can contain suboptimal practices. It’s the next step someone takes on their learning journey.
By comparing the stub (lib.rs) to the exemplar, we can work out what the introduction needs to teach. The introduction should only contain info about things used in the Exemplar that are not in the stub - ie the code someone writes. Other things can be touched on very loosely. Two examples from Lasagna:
We use +, - and * but we can also mention the existence of /. But we shouldn’t dwell on it.
We call functions, but we don’t create them. So we don’t need to explain pub or go into any detail about defining functions. But we should say “Rust has functions that are defined by use the keyword fn followed by the name. (You’ll also see visibility modifiers and param/return types, but don’t worry about those for now). You call functions by using the name and passing any arguments in parenthesis.”
For extra information that isn’t used in the Exemplar, but is topical, this should go in the after.md (which can be thought of as the introduction.md + extra info). Think of this after.md as more evergreen information on the concept.
So I’m going to go through and make notes on each one. I’m only looking at the exemplar and stub.
Lucians Luscious Lasagna (Basics)
I need to be taught:
Calling functions
-, +, *
Implicit returns
We also use this to cover any other basic information. However, looking at the current introduction there’s loads of unnecessary information in there. For example, we need nothing about let at this stage as it’s not used in the exercise, so let’s pull that out and use it in a different exercise later.
Does everyone agree with that analysis? What have I missed?
When we have consensus on that analysis, Dinesh, refine the introductions to achieve the points, and then tell people when you feel they’re ready for review. Then we can all weigh in.
There are some missing numeric operators which need to be thought also that concept teaches the basics of int and float.
Why are we using explicit returns here but implicit returns in lasagna. Let’s standardize
Different author, different style. We should be using implicit returns in any case (in my opinion).
Why does this exercise have semicolons?
Since you need to have semicolons in rust unless it is the last line
Whatever info.1 is
A form of indexing
split_at(1).1
Same
Does everyone agree with that analysis? What have I missed?
My thought would be to drop Implicit returns from the first exercise.
This may just be me but I find that teaching let in the basic concept is something that should be done.
I agree Annalyn’s Infiltration should not use return.
Yes, a ‘method’. Beware though: different languages mean different things by this term.
Rust doesn’t have classes or objects and such. As far as I know Rust’s ‘methods’ are just regular functions, except sorta-namespaced and with convenient syntax.
(input * 10.0).round()
// means the same thing as
f64::round(input * 10)
Cars Assemble also uses if, explicit return, and type casts.
Interest is Interesting uses the (void) add-assign operator+=.
This is struct field access. Tuples do not have named fields, but you can still get at them using this syntax. tuple.1 is the tuple’s second field, i.e. element.
That’s actually pattern matching (against a tuple).
A few other exercises have semicolons too.
Rust’s blocks ({ … }) are expressions. They consist of a series of ‘statements’ separated by semicolons, and their value is the value of the last statement. If the last statement is terminated with a semicolon (or, if you will, the last statement is empty) then the value of the block is () (the empty tuple / maximally boring value).
You could see the return keyword as syntactic sugar that makes it convenient to ‘return’ earlier.
I am quite sure that floats are defined in a struct and a struct if not object-oriented, so is it very close. And that struct has methods assigned to it. Methods and functions are different, but in this situation, they should be called methods since they correspond to an instance of a struct.
But of course there are functions as well, but when calling number.method so will it always be a method. Calling f64::round() is a function (I am pretty sure)