-
Notifications
You must be signed in to change notification settings - Fork 0
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
Parameter interface strictness #2
Comments
The proposed solution has a drawback: PHP's type hints are currently invariant: an implementation must exactly match the interface. With contravariant parameter types and covariant return types, a clean solution becomes quite obvious. However, a totally clean solution that keeps static analysis happy, might not exist until we get at least covariant return types. More information: |
Another good (and much simpler) example that exposes this problem is the |
This article might have some clues to deal with the problem: https://www.moxio.com/blog/17/on-type-safety-without-generics-and-the-role-of-package-design We may use the Adapter Pattern to circumvent the need for templating and to cope with proper variance. |
Perhaps it's worth checking whether we can use a // (interface Player)
/**
* @param static $player
*/
function equals(Player $player): bool;
// (interface GameState)
/**
* @return static[]
*/
function getPossibleMoves(): array; |
The
Decision
interface prescribes an apply method receiving aGameState
parameter, which is itself also an interface. This makes sense from an interface standpoint, but it constrains an implementer that applies strict static analysis.The reason is that a concrete
MyDecision
wants a concreteMyGameState
as a parameter, in order to actually do something useful such as filling a field on the board. However, since the interface prescribes aGameState
parameter, this is not possible without agitating static analysis tools. (Such as phpstan with a high enough strictness level.)Conceptually this could be solved by templating in languages that support it. In PHP however we need to look to other solutions. Perhaps a concrete
Decision
can already take its original concreteGameState
via the constructor so that the interface does not need to know about it? SinceDecisions
are constructed by concreteGameStates
, this keeps all concreteness at the implementer's side.The text was updated successfully, but these errors were encountered: