Skip to content

Add strong ID type infrastructure + NodeID #129

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

Merged
merged 1 commit into from
Jul 21, 2021
Merged

Add strong ID type infrastructure + NodeID #129

merged 1 commit into from
Jul 21, 2021

Conversation

molpopgen
Copy link
Member

This PR starts a discussion about strengthening the ID types in tskit-rust.
See #128 for background.

@molpopgen
Copy link
Member Author

molpopgen commented Jul 20, 2021

So, it is not quite API-preserving:

  • A perhaps key issue is that we have to break the return type, TskReturnValue, defined in src/lib.rs.
  • It'd be nice to be able to have as casts to, say, usize, rather than needing usize::from.
  • Comparisons to NULL either need a new trait (which then needs importing), use TSK_NULL.into(), which is a bit inelegant (and API-breaking), or a new, generic, "check if the ID is null function", which is fine in the long run imposes short-term API pain.

cc @MomoLangenstein @hyanwong

@molpopgen
Copy link
Member Author

molpopgen commented Jul 20, 2021

Clippy is failing due to rust-lang/rust-bindgen#2049 and rust-lang/rust-bindgen#1651

@molpopgen
Copy link
Member Author

A quick performance check suggests no loss of performance in the example forward sim.

@molpopgen molpopgen marked this pull request as draft July 21, 2021 00:09
@molpopgen
Copy link
Member Author

The much more difficult part is to update src/node_table.rs to take the right kind of ID. Much of the API makes use of macros to generate code for patterns common to all table types. This design makes it tedious to update one table at a time without breaking others.

@juntyr
Copy link
Contributor

juntyr commented Jul 21, 2021

So, it is not quite API-preserving:

  • A perhaps key issue is that we have to break the return type, TskReturnValue, defined in src/lib.rs.

That is actually a good change in my opinion. I personally dislike when Results are hidden behind type aliases. I would either remove the alias or make it generic (a popular solution in other crates):

type TskReturnValue<T> = Result<T, TskitError>;
  • It'd be nice to be able to have as casts to, say, usize, rather than needing usize::from.

From what I know, that is impossible. as casts are a language feature only for casting between primitive types.

  • Comparisons to NULL either need a new trait (which then needs importing), use TSK_NULL.into(), which is a bit inelegant (and API-breaking), or a new, generic, "check if the ID is null function", which is fine in the long run imposes short-term API pain.

You could add this new trait, add a new function, or implement PartialEq<tsk_id_t> and PartialOrd<tsk_id_t> for the new types. Then, you can compare them directly with the const.

@juntyr
Copy link
Contributor

juntyr commented Jul 21, 2021

Clippy is failing due to rust-lang/rust-bindgen#2049 and rust-lang/rust-bindgen#1651

I thought you disabled clippy checks for the auto generated code? Right now, chippy seems to fail on actual compilation errors. Anyways, there are much stronger checks that you could enable for this project. If you’d like, I could open a PR for that after we have finished this one.

@molpopgen
Copy link
Member Author

I thought you disabled clippy checks for the auto generated code? Right now, chippy seems to fail on actual compilation errors. Anyways, there are much stronger checks that you could enable for this project. If you’d like, I could open a PR for that after we have finished this one.

No, clippy hits everything. This issue with bindgen is new to stable/beta. As for a PR w/more checks, that can happen any time. There's no guarantee that this one is getting merged. And, if it does, it won't be anytime soon. There's a lot of nuance here. And even if this does work out, there are 3-4 more downstream PRs needed for all the other ID types.

@juntyr
Copy link
Contributor

juntyr commented Jul 21, 2021

I thought you disabled clippy checks for the auto generated code? Right now, chippy seems to fail on actual compilation errors. Anyways, there are much stronger checks that you could enable for this project. If you’d like, I could open a PR for that after we have finished this one.

No, clippy hits everything. This issue with bindgen is new to stable/beta. As for a PR w/more checks, that can happen any time. There's no guarantee that this one is getting merged. And, if it does, it won't be anytime soon. There's a lot of nuance here. And even if this does work out, there are 3-4 more downstream PRs needed for all the other ID types.

In

#![allow(clippy::all)]
you are allowing everything - but maybe it’s not caught since you are using the #! syntax outside the crate root. Maybe you could just apply the attribute to the module declaration in:
pub mod bindings;

#[allow(clippy::all)]
pub mod bindings;

@molpopgen
Copy link
Member Author

I thought you disabled clippy checks for the auto generated code? Right now, chippy seems to fail on actual compilation errors. Anyways, there are much stronger checks that you could enable for this project. If you’d like, I could open a PR for that after we have finished this one.

No, clippy hits everything. This issue with bindgen is new to stable/beta. As for a PR w/more checks, that can happen any time. There's no guarantee that this one is getting merged. And, if it does, it won't be anytime soon. There's a lot of nuance here. And even if this does work out, there are 3-4 more downstream PRs needed for all the other ID types.

In

#![allow(clippy::all)]

you are allowing everything - but maybe it’s not caught since you are using the #! syntax outside the crate root. Maybe you could just apply the attribute to the module declaration in:

pub mod bindings;

#[allow(clippy::all)]
pub mod bindings;

I'll try this in a separate PR, as it is a separate issue. It came out of nowhere as I've not done any rust work in months, and these warnings only hit due to a recent update.

@molpopgen
Copy link
Member Author

For the record, moving the "allow clippy all" doesn't fix the problem. I just tried this as a standalone change with respect to the main branch.

@juntyr
Copy link
Contributor

juntyr commented Jul 21, 2021

For the record, moving the "allow clippy all" doesn't fix the problem. I just tried this as a standalone change with respect to the main branch.

Thanks for trying!

@molpopgen
Copy link
Member Author

For the record, moving the "allow clippy all" doesn't fix the problem. I just tried this as a standalone change with respect to the main branch.

Thanks for trying!

It is quite annoying: cargo cllippy never triggers the warnings, but adding --all-targets does, and that option is VERY useful.

@molpopgen
Copy link
Member Author

molpopgen commented Jul 21, 2021

Now that all tests are passing, I'm going to let this simmer a bit. There are a few nagging issues, but none that can't be handled in a later PR:

  1. No real docs for the new type.
  2. Few tests that start with this type, although the From/Into business and the example simulation program gives us good coverage of round-tripping to/from the tsk_id_t.
  3. It may be worth implementing Add for this type.

@juntyr
Copy link
Contributor

juntyr commented Jul 21, 2021

Now that all tests are passing, I'm going to let this simmer a bit. There are a few nagging issues, but none that can't be handled in a later PR:

  1. No real docs for the new type.

That’s a good idea - though 1-2 sentences and a link to the newtype pattern might suffice.

  1. Few tests that start with this type, although the From/Into business and the example simulation program gives us good coverage of round-tripping to/from the tsk_id_t.
  2. It may be worth implementing Add for this type.

In which situations would you want to perform arithmetic on this type?

@molpopgen
Copy link
Member Author

In which situations would you want to perform arithmetic on this type?

Book-keeping of "the next offspring node" is sometimes handing for forward-time simulations. You may say something like x = x + number of births that have happened. But perhaps using i32 and From solves all of that.

@molpopgen
Copy link
Member Author

That’s a good idea - though 1-2 sentences and a link to the newtype pattern might suffice.

I guess I need to figure out how to do this using rust's doc system. It is a bit limited compared to what we are used to over in Pythonlandia.

* Implement the pattern via a macro
* Add NodeId as the first concrete example

This PR breaks API, although the changes required are small.
See examples/forward_simulation.rs.
@molpopgen molpopgen marked this pull request as ready for review July 21, 2021 14:02
@molpopgen
Copy link
Member Author

I'm pretty confident that this is the way to go. I'll sort out the other ID types in future PRs, in case we ever need to git bisect our way out of something nasty. More docs can also happen later.

@molpopgen
Copy link
Member Author

Gonna merge this in a minute--thanks for the input @MomoLangenstein!

@molpopgen molpopgen merged commit 3ac3d50 into main Jul 21, 2021
@molpopgen molpopgen deleted the add_NodeID branch July 21, 2021 14:07
molpopgen added a commit that referenced this pull request Jul 21, 2021
molpopgen added a commit that referenced this pull request Jul 21, 2021
@molpopgen molpopgen linked an issue Jul 21, 2021 that may be closed by this pull request
8 tasks
@molpopgen molpopgen changed the title Starting point to add NodeId Add strong ID type infrastructure + NodeID Jul 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Strong typing for IDs
2 participants