Hi,
May I suggest adding a little "instanceof" magic to match? Like this:
match ($object) {
Someinterface => 'foo',
AnotherInterface => 'bar',
}
this can not clash with any existing code as using identifiers like this
are a syntax error currently.
Currently you could do the same with
match (true) {
$object instanceof Someinterface::class => 'foo',
$object instanceof AnotherInterface::class => 'bar',
}
Indeed, the former could be considered syntactic sugar for the latter. And
I do not think there's any ambiguity here for the casual reader or is it
just me who thinks no other sensible reading is possible?
Thanks for your consideration.
Karoly Negyesi
match ($object) {
Someinterface => 'foo',
AnotherInterface => 'bar',
}this can not clash with any existing code as using identifiers like this
are a syntax error currently.
That's valid code actually, see https://3v4l.org/BEcE4
match ($object) {
Someinterface => 'foo',
AnotherInterface => 'bar',
}this can not clash with any existing code as using identifiers like this
are a syntax error currently.That's valid code actually, see https://3v4l.org/BEcE4
--
To unsubscribe, visit: https://www.php.net/unsub.php
It can be modified to produce ambiguous code however:
const SomeInterface = 1;
const AnotherInterface = 2;
interface SomeInterface {}
interface OtherInterface {}
$object = new class implements SomeInterface {};
var_dump(
match (true) {
$object instanceof SomeInterface => 'foo',
$object instanceof AnotherInterface => 'bar',
}
);
We can see that SomeInterface
will resolve the interface and not the
constant.
I think what they are proposing is that when the match is an object,
and the branches are class/interface/etc names, it should just do an
instanceof
operation instead of a value-equals operation.
$object instanceof AnotherInterface => 'bar',
We can see that
SomeInterface
will resolve the interface and not the
constant.
Yeah, the instanceof operator is magic in that regard - it has a special
parsing rule to consume the next token and avoid it being evaluated as a
constant.
I think what they are proposing is that when the match is an object,
and the branches are class/interface/etc names, it should just do an
instanceof
operation instead of a value-equals operation.
That wouldn't work, because the type of value passed to match() can vary
at run-time, but you'd need to compile the expression one way or the other.
If it did work, it would be extremely confusing:
function example(string|object $input) {
return match($input) {
SomeClass => 'found class',
SOME_CONSTANT => 'found constant',
};
}
var_dump( example(new SomeClass) );
var_dump( example(SOME_CONSTANT) );
Do both of those matches succeed? What if I set const SomeClass = 'hello';
?
So unfortunately we need some extra syntax to say that something should
be an instanceof check, and therefore a class name.
Regards,
--
Rowan Tommins
[IMSoP]
Hi,
Am 29.03.22 um 14:34 schrieb Rowan Tommins:
$object instanceof AnotherInterface => 'bar',
We can see that
SomeInterface
will resolve the interface and not the
constant.Yeah, the instanceof operator is magic in that regard - it has a special
parsing rule to consume the next token and avoid it being evaluated as a
constant.I think what they are proposing is that when the match is an object,
and the branches are class/interface/etc names, it should just do an
instanceof
operation instead of a value-equals operation.That wouldn't work, because the type of value passed to match() can vary
at run-time, but you'd need to compile the expression one way or the other.If it did work, it would be extremely confusing:
function example(string|object $input) {
return match($input) {
SomeClass => 'found class',
SOME_CONSTANT => 'found constant',
};
}
var_dump( example(new SomeClass) );
var_dump( example(SOME_CONSTANT) );Do both of those matches succeed? What if I set
const SomeClass = 'hello';
?So unfortunately we need some extra syntax to say that something should
be an instanceof check, and therefore a class name.
While I liked the intention of Karoly, I did not like the proposed magic.
Would it be an idea (and possible) to extend the syntax somehow like:
$result = match ($value) {
instanceof MyObject => ...,
>= 42 => ...,
!== 5 => ...
};
to be equivalent to:
$result = match (true) {
$value instanceof MyObject => ...,
$value >= 42 => ...,
$value !== 5 => ...
};
Regards
Thomas
On mardi 29 mars 2022 15:33:41 CEST Thomas Nunninger wrote:
Hi,
Am 29.03.22 um 14:34 schrieb Rowan Tommins:
$object instanceof AnotherInterface => 'bar',
We can see that
SomeInterface
will resolve the interface and not the
constant.Yeah, the instanceof operator is magic in that regard - it has a special
parsing rule to consume the next token and avoid it being evaluated as a
constant.I think what they are proposing is that when the match is an object,
and the branches are class/interface/etc names, it should just do an
instanceof
operation instead of a value-equals operation.That wouldn't work, because the type of value passed to match() can vary
at run-time, but you'd need to compile the expression one way or the
other.If it did work, it would be extremely confusing:
function example(string|object $input) {
return match($input) { SomeClass => 'found class', SOME_CONSTANT => 'found constant', };
}
var_dump( example(new SomeClass) );
var_dump( example(SOME_CONSTANT) );Do both of those matches succeed? What if I set
const SomeClass = 'hello';
?So unfortunately we need some extra syntax to say that something should
be an instanceof check, and therefore a class name.While I liked the intention of Karoly, I did not like the proposed magic.
Would it be an idea (and possible) to extend the syntax somehow like:
$result = match ($value) {
instanceof MyObject => ...,>= 42 => ..., !== 5 => ...
};
to be equivalent to:
$result = match (true) {
$value instanceof MyObject => ...,
$value >= 42 => ...,
$value !== 5 => ...
};Regards
Thomas
I like this.
The pattern matching RFC may also cover this:
https://wiki.php.net/rfc/pattern-matching
-- Arnaud
Hi,
May I suggest adding a little "instanceof" magic to match? Like this:
match ($object) {
Someinterface => 'foo',
AnotherInterface => 'bar',
}
this can not clash with any existing code as using identifiers like this
are a syntax error currently.
Currently you could do the same with
match (true) {
$object instanceof Someinterface::class => 'foo',
$object instanceof AnotherInterface::class => 'bar',
}
Indeed, the former could be considered syntactic sugar for the latter. And
I do not think there's any ambiguity here for the casual reader or is it
just me who thinks no other sensible reading is possible?
Thanks for your consideration.
Karoly Negyesi
Hi Karoly,
As mentioned by Bruce, this syntax is already valid, therefor, it can't be used.
what you are looking for is pattern-matching, see "match()
enhancement" section in the RFC: https://wiki.php.net/rfc/pattern-matching
Regards,
Saif Eddin Gmati.