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

Returning null instead of false on failure for first/last/current/next #362

Closed
wants to merge 1 commit into from

Conversation

jeromegxj
Copy link

This PR references #190

The idea is to have the ReadableCollection interface and ArrayCollection implementation of the method first, last, current and next returns null instead of false.

This way we can use PHP nullsafe operator like this:

if ($collection?->first()->isActive()) { /* do something */ }

Let me know what are the next steps

@@ -88,15 +88,15 @@ public function toArray();
* Sets the internal iterator to the first element in the collection and returns this element.
*
* @return mixed
* @psalm-return T|false
* @psalm-return T|null
Copy link
Member

Choose a reason for hiding this comment

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

This is a breaking change: consumers would need to change their code after upgrading to null checks instead of false checks. Implementors would need to change their code to return null instead of `false.
Breaking changes should go on 3.x, but that's not all: there should be an upgrade path for both consumers and implementors, meaning there should be a way to be compatible with both 2.x and 3.x.

For consumers, that would mean checking for false AND for null. For implementors (for instance PersistentCollection in doctrine/orm), it would mean returning null or false depending on whether 2.x or 3.x is installed. That's kind of a breaking change, although it's unlikely people are use PersistentCollection as a type declaration. They are probably referring to ArrayCollection instead, which in turns means they should have a dependency on doctrine/collection in their composer.json.

Copy link
Author

Choose a reason for hiding this comment

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

Yes indeed, it is fine to be in 3.x, I agree, it is a big change.
I'm willing to make the documentation for this BC, please point me to some previous documentation that cover some similar change to get inspiration from.

Or I can work on a 2.x implementation that will live into the current interface, adding methods like: firstOrNull, lastOrNull, currentOrNull and nextOrNull but it feels that it does not belong here.

Copy link
Member

Choose a reason for hiding this comment

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

Adding methods to an interface is a breaking change, not for consumers but for implementors, so that's out of the question anyway.

Breaking changes are documented at https://github.com/doctrine/collections/blob/2.1.x/UPGRADE.md

Copy link
Author

Choose a reason for hiding this comment

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

(...) but that's not all: there should be an upgrade path for both consumers and implementors, meaning there should be a way to be compatible with both 2.x and 3.x.

Reading this piece makes me feel that this PR is too big of a change? The underlying idea was to allow the consumer to benefit from the nullsafe operator but if in the meantime they must check for either false or null all the benefit is lost.

Am I missing something?

Copy link
Member

Choose a reason for hiding this comment

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

I understand you motivation, but indeed I wouldn't change the semantics of those methods. It's not worth it.

If we really wanted to go that way, we would need to introduce an entirely new contract (== interface) with different methods and phase out the old one.

Copy link
Author

Choose a reason for hiding this comment

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

Not a problem, let's close this PR. Still I guess we should raise those reflections back to the original issue #190, so it is not lost?

Copy link
Member

Choose a reason for hiding this comment

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

Sure.

ReadableCollection::last returns null if no item found
ReadableCollection::current returns null if no item found
ReadableCollection::next returns null if no item found

# Conflicts:
#	src/ReadableCollection.php
@jeromegxj jeromegxj changed the base branch from 2.1.x to 3.0.x February 22, 2023 07:21
@jeromegxj jeromegxj marked this pull request as draft February 22, 2023 07:23
@derrabus
Copy link
Member

Closing as discussed.

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.

None yet

3 participants