Skip to content
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

Sequence equality #249

Open
wants to merge 60 commits into
base: main
Choose a base branch
from
Open

Conversation

frenchy64
Copy link
Contributor

@frenchy64 frenchy64 commented Feb 7, 2025

Closes #243
Closes #250
Closes #251
Closes #274

It would be nice to replace nullptr returns with nil in sequenceable but it enables important optimizations for calls to sequenceable member functions. I did not investigate returning option types.

@frenchy64 frenchy64 changed the title [wip] range equality [wip] sequence equality Feb 7, 2025
@frenchy64 frenchy64 changed the title [wip] sequence equality Sequence equality Feb 22, 2025
@frenchy64 frenchy64 marked this pull request as ready for review February 22, 2025 08:49
@frenchy64 frenchy64 requested a review from jeaye February 22, 2025 08:49
Copy link
Member

@jeaye jeaye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of good fixes in here. I think there are some introduced bugs though. I tried to pick them out.

return !lhs;
return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change this? Right now, it would treat two null object ptrs as equal. This would also carry over to us removing nullptr support for boxes, such that two nils would be equal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I missed that box overloaded !.

Copy link
Contributor Author

@frenchy64 frenchy64 Feb 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, could you look at this again? At this point we already know !lhs is false, so I think returning either is equivalent.

Would this be another way of writing the test?

if(!lhs != !rhs) return false

EDIT: No, because that is false when both are null.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added assertions to point out my reasoning.

return true;
return seq == nullptr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct. In the case where this is a shorter seq than o, we would finish our for loop and then need to check if there is some seq left over.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case where this is a shorter seq than o, we would finish our for loop and then need to check if there is some seq left over.

This is my attempt at adding that check. At this point, we've already called next_in_place(seq), and seq will be nullptr if there's none left over.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're talking about the same diff, right?

-       return true;
+       return seq == nullptr;

@@ -77,12 +77,12 @@ namespace jank::runtime::obj
for(auto it(fresh_seq()); it != nullptr;
it = runtime::next_in_place(it), seq = runtime::next_in_place(seq))
{
if(seq == nullptr || !runtime::equal(it, seq->first()))
if(seq == nullptr || !runtime::equal(it->first(), seq->first()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a good fix. We'd need the same thing for chunked_cons above, though. I wonder where else this cropped up. I have a TODO for sequence equality having a lot of copy pasta.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd need the same thing for chunked_cons above, though.

Done.

I wonder where else this cropped up.

Several places. I think I reverted some of them accidentally when experimenting with replace nullptr with nil_const(), I'll have another look.

I have a TODO for sequence equality having a lot of copy pasta.

I wasn't sure how to tackle it, but I can at least write more tests so then the abstraction can be validated easily.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't worry about removing support for nullptr yet. Certainly not in this PR, which already has a lot going on.

Copy link
Member

@jeaye jeaye Feb 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure how to tackle it, but I can at least write more tests so then the abstraction can be validated easily.

I have some ideas for how to do it. The tests are very welcome, though.

@frenchy64
Copy link
Contributor Author

frenchy64 commented Feb 23, 2025

Found and fixed a couple more issues while I scanned everything. Lmk if I should pull them out.

  • apply_to isn't compatible with seqs that return fresh seqs from next_in_place. Not sure if they exist, but persistent_list is implemented that way.
  • removed transient cases to resolve Transients mutate in-place on persistent ops #274
    • extra: conj case for seqables didn't seem right to me compared to Clojure, so I removed it. For one, it changes the type of the seqable to a seq.
  • added paranoid assertions for nil while the function/template ambiguity exists for runtime::{next,seq,next_in_place,fresh_seq}.

@frenchy64 frenchy64 requested a review from jeaye February 23, 2025 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants