Re: [RFC] Default expression
| From: | Rowan Tommins [IMSoP] | Date: | Mon, 26 Aug 2024 10:58:12 +0000 |
| Subject: | Re: [RFC] Default expression | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-125266@lists.php.net to get a copy of this message | ||
On Mon, 26 Aug 2024, at 10:03, Andreas Leathley wrote:
> interface CompressionInterface
> {
> public function compress(string $data, int $level): string;
> }
>
> class GzipCompression implements CompressionInterface
> {
> public function compress(string $data, int $level = 4): string
> {
> // do something
> }
> }
>
> When I have the GzipCompression class, I would know there is a default
> value for $level, but when using the interface there might or might not
> be a default value, depending on the implementation.
This isn't unique to defaults; GzipCompression could also widen the type to int|string, for
instance, and there's no syntax for detecting that either.
If you have access to change class GzipCompression, you can resolve this by creating an additional
interface:
interface SimplifiedCompressionInterface extends CompressionInterface
{
public function compress(string $data, int $level = 4): string;
}
class GzipCompression implements SimplifiedCompressionInterface ...
Then, if we can agree an implementation, you could write:
/** @var CompressionInterface $comp */
$comp->compress($myData, $comp instanceof SimplifiedCompressionInterface ? default :
MY_DEFAULT_LEVEL);
If you don't have access to change the hierarchy, then what you're probably looking for is
structural typing, or implicit interfaces - i.e. a way to ask "does this object meet these
criteria". For instance, some imaginary pattern matching on the signature:
/** @var CompressionInterface $comp */
$comp->compress($myData, $comp is { compress(string, optional int) } ? default :
MY_DEFAULT_LEVEL);
Note how, in both cases, we're not asserting anything about the default value itself, only that
the signature defines the parameter as optional. It's actually a bit of a quirk that the
interface has to specify a value, rather than just stating this:
interface SimplifiedCompressionInterface extends CompressionInterface
{
public function compress(string $data, optional int $level): string;
}
Regards,
--
Rowan Tommins
[IMSoP]