-
Notifications
You must be signed in to change notification settings - Fork 544
react: Distinguish cell IDs #499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Well, I guess this is it. |
exercises/react/example.rs
Outdated
@@ -1,12 +1,13 @@ | |||
use std::collections::HashMap; | |||
|
|||
pub type CellID = usize; | |||
pub type InputCellID = usize; | |||
pub type ComputeCellID = usize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I note that these are typedefs, not newtypes. As such, the compiler treats InputCellID
, ComputeCellID
, and usize
interchangeably. If we want it to enforce real type safety for us, we'll need to use newtypes:
pub struct InputCellID(usize);
pub struct ComputeCellID(usize);
// the above two types _cannot_ be interchanged
exercises/react/src/lib.rs
Outdated
pub type CellID = (); | ||
// it will probably be necessary for these three types to be Copy. | ||
pub type InputCellID = (); | ||
pub type ComputeCellID = (); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth declaring these as
pub struct InputCellID();
pub struct ComputeCellID();
to suggest the newtype pattern instead of the typedef pattern.
Interestingly, I believe that the tests don't care; they should work whether these are type aliases or newtypes. Still, if we're in this for the type safety, we may as well do it right.
I would like to experiment with adding a compile_fail test (docmented in https://doc.rust-lang.org/stable/rustdoc/documentation-tests.html) to ensure IDs aren't mutually assignable. |
This ensures type safety; the types should not be assignable to one another.
Can no longer error via being given a compute ID, so the only error is a nonexistent cell.
exercises/react/src/lib.rs
Outdated
pub type CallbackID = (); | ||
#[derive(Clone, Copy, Debug, PartialEq)] | ||
pub struct ComputeCellID(); | ||
#[derive(Clone, Copy, Debug, PartialEq)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the tests are going to need all of these. The reason why Debug
and PartialEq
should be obvious.
The reason for Copy (and therefore why Clone) is:
error[E0382]: use of moved value: `callback`
--> tests/react.rs:203:52
|
201 | assert!(reactor.remove_callback(output, callback).is_ok());
| -------- value moved here
202 | for _ in 1..5 {
203 | assert_eq!(reactor.remove_callback(output, callback), Err(RemoveCallbackError::NonexistentCallback));
| ^^^^^^^^ value used here after move
|
= note: move occurs because `callback` has type `react::CallbackID`, which does not implement the `Copy` trait
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay reviewing this. It looks good!
Exercises such as this form a useful jumping-off point for students into the kind of code they should expect to read and write in the real world, so I am very much in favor of the improved type safety here.
pub struct InputCellID(); | ||
/// `ComputeCellID` is a unique identifier for a compute cell. | ||
/// Values of type `InputCellID` and `ComputeCellID` should not be mutually assignable, | ||
/// demonstrated by the following tests: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if cargo doc
flags to the user that the code under test here should fail to compile. If it does, no changes are required. If it does not, it's probably worth mentioning in the text that both of the examples here should fail to compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did manage to confirm this. There's a red ⓘ and hovering over it shows "this example deliberately fails to compile"
Given this, I'll be merging it. Just not now, since it is inconvenient to now.
Thanks for reviewing! |
Closes #473
I strongly advise that this should not be merged yet, for at least the following reason:set_cell_value
now can only fail in one way (cell does not exist) since it is no longer possible to designate an input cell to it. Therefore, it no longer needs to returnSetValueError
. We can just return a boolean, even.Except for that point, I guess everything else is how I expect it to be.
I'm also happy to hear ideas about being able to move
set_value
onto input cells directory, in which case I don't see the need for this PR.