Hi all,
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehint
This feature is developed to provide missing functionality which is needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.
For those who doesn't like the idea and think they won't need neither use
it rather than just saying 'no' they
please say why other people who want to use that parameter type are wrong,
for wanting to do that.
If there is anything left to discuss, please comment.
Thanks to @Danack for drafting.
regards / pozdrawiam,
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com
On Sun, Oct 23, 2016 at 1:39 AM, Michał Brzuchalski
michal@brzuchalski.com wrote:
Hi all,
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehintThis feature is developed to provide missing functionality which is needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.For those who doesn't like the idea and think they won't need neither use
it rather than just saying 'no' they
please say why other people who want to use that parameter type are wrong,
for wanting to do that.If there is anything left to discuss, please comment.
Thanks to @Danack for drafting.
regards / pozdrawiam,
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com
I generally don't mind keywords/new classes being added to minor
versions. However I am nervous about this one as I am sure there are a
lot of class Object
floating around. Maybe this would be best suited
for 8.0 with E_DEPRECATED
being emitted to warn people of the
up-coming change? Also, can the RFC be edited to give an example of
how people will be affected?
Other than this issue I support this RFC.
On Sun, Oct 23, 2016 at 1:39 AM, Michał Brzuchalski
michal@brzuchalski.com wrote:Hi all,
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehintThis feature is developed to provide missing functionality which is
needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.For those who doesn't like the idea and think they won't need neither use
it rather than just saying 'no' they
please say why other people who want to use that parameter type are
wrong,
for wanting to do that.If there is anything left to discuss, please comment.
Thanks to @Danack for drafting.
regards / pozdrawiam,
Michał Brzuchalski
about.me/brzuchal
brzuchalski.comI generally don't mind keywords/new classes being added to minor
versions. However I am nervous about this one as I am sure there are a
lot ofclass Object
floating around. Maybe this would be best suited
for 8.0 withE_DEPRECATED
being emitted to warn people of the
up-coming change? Also, can the RFC be edited to give an example of
how people will be affected?Other than this issue I support this RFC.
Without commenting on the proposal itself, we did explicitly reserve the
"object" typehint in PHP 7:
https://wiki.php.net/rfc/reserve_even_more_types_in_php_7 While this
reservation does not carry a runtime error, we do document that "usage of
them is highly discouraged since they may be used in future versions of
PHP." As such, we have given advance warning that this was likely to happen.
Nikita
Hi!
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehint
I don't see why it would be important that the variable is an object but
not important which kind of an object. There's very small number of
things you can do with an object without knowing the exact type. For
generic functions, like serialization, there's no reason why they
shouldn't be able to serialize integers or nulls or booleans. On the
contrary, many objects would not be serializable. For less generic
functions, like DI containers, object type is next to useless since you
can't just pass any object to implement a service - it should actually
implement the required service. So adding "object" does not add real
specificity to it.
This feature is developed to provide missing functionality which is needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.For those who doesn't like the idea and think they won't need neither use
it rather than just saying 'no' they
please say why other people who want to use that parameter type are wrong,
for wanting to do that.
They probably think more "strictness" and more checks means better code.
It is usually not true per se. E.g. in the RFC examples the type does
not seem to be serving a good purpose - it's either wrong (like in the
case of json_decode - it won't always return an object), or nonspecific
- like in factory, very rarely one has a factory returning just
arbitrary objects, no matter what they are.
--
Stas Malyshev
smalyshev@gmail.com
I can see uses for it, although none of them are impossible without the object typehint - they currently do an is_object()
check.
In the same way that Iterable type hint allows you to safely do a foreach on an argument, object allows you to safely use property accessor syntax (i.e. ->). For me it would be most useful in lower level utility classes.
Cheers
Stephen
Hi!
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehintI don't see why it would be important that the variable is an object but
not important which kind of an object. There's very small number of
things you can do with an object without knowing the exact type. For
generic functions, like serialization, there's no reason why they
shouldn't be able to serialize integers or nulls or booleans. On the
contrary, many objects would not be serializable. For less generic
functions, like DI containers, object type is next to useless since you
can't just pass any object to implement a service - it should actually
implement the required service. So adding "object" does not add real
specificity to it.This feature is developed to provide missing functionality which is needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.For those who doesn't like the idea and think they won't need neither use
it rather than just saying 'no' they
please say why other people who want to use that parameter type are wrong,
for wanting to do that.They probably think more "strictness" and more checks means better code.
It is usually not true per se. E.g. in the RFC examples the type does
not seem to be serving a good purpose - it's either wrong (like in the
case of json_decode - it won't always return an object), or nonspecific
- like in factory, very rarely one has a factory returning just
arbitrary objects, no matter what they are.
--
Stas Malyshev
smalyshev@gmail.com
Hi!
In the same way that Iterable type hint allows you to safely do a
foreach on an argument, object allows you to safely use property
accessor syntax (i.e. ->). For me it would be most useful in lower
level utility classes.
Not sure I get this point. How you can safely use -> if you have no idea
what object you've got? You certainly don't expect every object to have
the same properties?
--
Stas Malyshev
smalyshev@gmail.com
24.10.2016 07:05 "Stanislav Malyshev" smalyshev@gmail.com napisał(a):
Hi!
In the same way that Iterable type hint allows you to safely do a
foreach on an argument, object allows you to safely use property
accessor syntax (i.e. ->). For me it would be most useful in lower
level utility classes.Not sure I get this point. How you can safely use -> if you have no idea
what object you've got? You certainly don't expect every object to have
the same properties?
You don't need is_object any more you can safely check instanceof, use
Reflection, serialize etc.
--
Stas Malyshev
smalyshev@gmail.com
No, I don’t expect all objects to have the same properties.
So, today I learned that $foo = 1; isset($foo->bar);
doesn’t throw an error about a non-object. However, property_exists does throw errors in that situation, as does get_object_vars()
- two situations where you can pass any object, so long as it is an object.
Like I said, the functionality is possible without it. But what functionality was impossible without int/float/string type hints? They just make it much clearer, with less repeated boiler plate, what arguments you can actually accept.
Cheers
Stephen
Hi!
In the same way that Iterable type hint allows you to safely do a
foreach on an argument, object allows you to safely use property
accessor syntax (i.e. ->). For me it would be most useful in lower
level utility classes.Not sure I get this point. How you can safely use -> if you have no idea
what object you've got? You certainly don't expect every object to have
the same properties?--
Stas Malyshev
smalyshev@gmail.com
Hi!
Like I said, the functionality is possible without it. But what
functionality was impossible without int/float/string type hints?
I don't think it's a good argument "if we added something to the
language, from this point on anything can be added because why not?"
Yes, you can write code in machine code, and yes, we don't do that, but
that doesn't mean any addition to syntax anybody can think of
automatically is in because we once added syntax.
They just make it much clearer, with less repeated boiler plate, what
arguments you can actually accept.
I don't see how it's less boilerplate - in most cases, you don't even
need it, as I said, since checking for object is in most cases is
useless, you need to check for specific type. You don't use -> on just
random object. You use it on an object because you expect to find
something on the other end of -> and only objects of specific type(s)
would have it.
In very rare cases where it might may make sense, using is_object is
only marginally longer and is very clear. It's not like it's some weird
obscure function that takes ages to understand.
--
Stas Malyshev
smalyshev@gmail.com
Hi,
I didn’t suggest we add anything because why not. Knowing something is an object is quite similar to knowing something is an array, and we have type hints for those. You don’t know what the array holds exactly, but you know it’s an array and that you can call array methods safely without type errors.
I honestly don’t see the difference between the following (except that one is currently possible without extra is_* type checks):
foo(array $bar) {
if (array_key_exists(‘something’, $bar)) {…}
}
foo(object $bar) {
if (property_exists($bar, ‘something’) {…}
}
So to carry on from that, how is the above not less boiler plate than:
foo(object $bar) {
if (!is_object($bar)) {
throw new \InvalidArgumentException(‘foo expects parameter 1 to be an object, ‘ . gettype($bar) . ‘ given’);
}
if (property_exists($bar, ‘something’) {…}
}
Cheers
Stephen
Hi!
Like I said, the functionality is possible without it. But what
functionality was impossible without int/float/string type hints?I don't think it's a good argument "if we added something to the
language, from this point on anything can be added because why not?"
Yes, you can write code in machine code, and yes, we don't do that, but
that doesn't mean any addition to syntax anybody can think of
automatically is in because we once added syntax.They just make it much clearer, with less repeated boiler plate, what
arguments you can actually accept.I don't see how it's less boilerplate - in most cases, you don't even
need it, as I said, since checking for object is in most cases is
useless, you need to check for specific type. You don't use -> on just
random object. You use it on an object because you expect to find
something on the other end of -> and only objects of specific type(s)
would have it.In very rare cases where it might may make sense, using is_object is
only marginally longer and is very clear. It's not like it's some weird
obscure function that takes ages to understand.--
Stas Malyshev
smalyshev@gmail.com
On Sun, Oct 23, 2016 at 3:39 AM, Michał Brzuchalski michal@brzuchalski.com
wrote:
Hi all,
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehintThis feature is developed to provide missing functionality which is needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.For those who doesn't like the idea and think they won't need neither use
it rather than just saying 'no' they
please say why other people who want to use that parameter type are wrong,
for wanting to do that.
Type hinting, along with the assert statement, provide a means to establish
expectations for a methods. It's part of a coding paradigm known as 'design
by contract' and it's critical for large teams and projects that are used
among multiple teams.
Checking to see if a variable is an object in no way provides a real test
of what can be done with it. Can it be iterated on? Probably, but not
always. Does a method exist on the object? No way to know without further
testing.
Defining what an object can do is the reason interfaces exist. This is also
why objects are allowed to implement multiple interfaces, so that they can
be labeled according to all the roles they can fulfill.
My principle worry with this RFC is it encourages an anti-pattern - not
using interfaces and thereby not clearly labeling what objects can and
cannot do.
The one situation this might be useful requires additional testing anyway -
that would be a method that will receive objects of one or more classes
that don't have a common interface and rewriting the class to add the
desired interface isn't viable (for example, the objects come from
different packages). In that event though type hinting for an object is
only going to be the first step in determining if the code state is sane,
you'll also need to check if the object belongs to one of the several
classes the code can work with. This gets even hairier when dealing with a
collection of objects. I wrote this generic assertion for Drupal 8.
In your own code you'll likely need to do something similar with your
argument. Incidentally, these sorts of tests, which can only fail if the
code is wrong, are what assert statements are to be used for, not
exceptions. This way the check for correct objects can be turned off in
production to avoid the cpu overhead of the test (assuming your function
doesn't need to switch to different branches depending on the exact object
used).
In summary, -1 to this as it encourages bad code writing.
2016-10-24 8:45 GMT+02:00 Michael Morris tendoaki@gmail.com:
On Sun, Oct 23, 2016 at 3:39 AM, Michał Brzuchalski <
michal@brzuchalski.com>
wrote:Hi all,
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehintThis feature is developed to provide missing functionality which is
needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.For those who doesn't like the idea and think they won't need neither use
it rather than just saying 'no' they
please say why other people who want to use that parameter type are
wrong,
for wanting to do that.Type hinting, along with the assert statement, provide a means to establish
expectations for a methods. It's part of a coding paradigm known as 'design
by contract' and it's critical for large teams and projects that are used
among multiple teams.
assert statement cannot be defined in method declaration, using typehiunt
does
Anything inside a method can do the same - that's right, but none of those
assert
and even is_object cannot be in method declaration, that's why it cannot be
inherited
by sub-classes and that is why object
typehuiint is more powerfull
Additionally it more clear to read method declaration with static analysers
and detect abnormal usage simply by static analysis. It's impossible with
assertions!
Checking to see if a variable is an object in no way provides a real test
of what can be done with it. Can it be iterated on? Probably, but not
always. Does a method exist on the object? No way to know without further
testing.Defining what an object can do is the reason interfaces exist. This is also
why objects are allowed to implement multiple interfaces, so that they can
be labeled according to all the roles they can fulfill.
There are usage of object variables described in RFC which doesn't need any
behavior
from an object, they simply need variable to be object, and that's all,
thats the real world
use cases described in RFC.
Sorry but your argumentation doesn't convince me to not introduce described
feature.
My principle worry with this RFC is it encourages an anti-pattern - not
using interfaces and thereby not clearly labeling what objects can and
cannot do.
There are examples of use cases. Speaking of pattern the DI pattern is
designed
to provide services, they doesn't need to implement any specific interface.
There was a question earlier what about services - they need to implement
specific behaviour - but that's not true, you do not expect in DI pattern
any service
need to implement anything, you simply expect only services, which do need
to be
objects, and that is all the case. You cannot type hint against Service,
Closure etc,
because you don't know in DI what kind of service it is and that's not the
point of DI
The real point of DI is to provide service whatever it is, and that's why
object type is for.
The one situation this might be useful requires additional testing anyway -
that would be a method that will receive objects of one or more classes
that don't have a common interface and rewriting the class to add the
desired interface isn't viable (for example, the objects come from
different packages). In that event though type hinting for an object is
only going to be the first step in determining if the code state is sane,
you'll also need to check if the object belongs to one of the several
classes the code can work with. This gets even hairier when dealing with a
collection of objects. I wrote this generic assertion for Drupal 8.https://api.drupal.org/api/drupal/core%21lib%21Drupal%
21Component%21Assertion%21Inspector.php/function/Inspector%3A%
3AassertAllObjects/8.2.x
You're missing is_object on $member in foreach in your implementation
and it won't be even needed if there where object type hint.
In your own code you'll likely need to do something similar with your
argument. Incidentally, these sorts of tests, which can only fail if the
code is wrong, are what assert statements are to be used for, not
exceptions. This way the check for correct objects can be turned off in
production to avoid the cpu overhead of the test (assuming your function
doesn't need to switch to different branches depending on the exact object
used).In summary, -1 to this as it encourages bad code writing.
--
regards / pozdrawiam,
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com
On Mon, Oct 24, 2016 at 3:21 AM, Michał Brzuchalski michal@brzuchalski.com
wrote:
2016-10-24 8:45 GMT+02:00 Michael Morris tendoaki@gmail.com:
On Sun, Oct 23, 2016 at 3:39 AM, Michał Brzuchalski <
michal@brzuchalski.com>
wrote:https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Comp
onent%21Assertion%21Inspector.php/function/Inspector%3A%3Aas
sertAllObjects/8.2.xYou're missing is_object on $member in foreach in your implementation
Wrong - read the code more carefully. The function is variadic. If only 1
argument is passed then is_object is checked against all members of the
array to test. If 2 or more arguments are passed than the instanceof
operator is used instead. This operator will return false when testing non
objects.
and it won't be even needed if there where object type hint.
Wrong again. The method tests a collection (array or traversable) to see if
each member satisfies its test. Type hints do not work that way at all.
Even if they did, this code must work under PHP 5.5.
If you're going to criticize someone's code at least read over it
carefully. And it wouldn't hurt to check the unit tests either since they
do exist for this method. See here:
Best practice is to test for interfaces or more rarely classes. This RFC
encourages people to not do this so I'm not in favor of its inclusion.
2016-10-24 9:42 GMT+02:00 Michael Morris tendoaki@gmail.com:
On Mon, Oct 24, 2016 at 3:21 AM, Michał Brzuchalski <
michal@brzuchalski.com>
wrote:2016-10-24 8:45 GMT+02:00 Michael Morris tendoaki@gmail.com:
On Sun, Oct 23, 2016 at 3:39 AM, Michał Brzuchalski <
michal@brzuchalski.com>
wrote:https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Comp
onent%21Assertion%21Inspector.php/function/Inspector%3A%3Aas
sertAllObjects/8.2.xYou're missing is_object on $member in foreach in your implementation
Wrong - read the code more carefully. The function is variadic. If only 1
argument is passed then is_object is checked against all members of the
array to test. If 2 or more arguments are passed than the instanceof
operator is used instead. This operator will return false when testing non
objects.and it won't be even needed if there where object type hint.
Wrong again. The method tests a collection (array or traversable) to see if
each member satisfies its test. Type hints do not work that way at all.
Even if they did, this code must work under PHP 5.5.If you're going to criticize someone's code at least read over it
carefully. And it wouldn't hurt to check the unit tests either since they
do exist for this method. See here:
You're right I didn't read it carefully. I was in my way to work and little
bit hurry.
also it is true that my patch doesn't affect your use case in any way
you've pointed out.
https://api.drupal.org/api/drupal/core%21tests%21Drupal%
21Tests%21Component%21Assertion%21InspectorTest.
php/function/InspectorTest%3A%3AtestAssertAllObjects/8.2.xBest practice is to test for interfaces or more rarely classes. This RFC
encourages people to not do this so I'm not in favor of its inclusion.
--
regards / pozdrawiam,
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com
My principle worry with this RFC is it encourages an anti-pattern - not
using interfaces and thereby not clearly labeling what objects can and
cannot do.
You've stated that as fact without any supporting argument, as far as I can see.
Any piece of functionality can be abused and used for purposes other that the use-cases which it was intended for.
But I don't see how this RFC 'encourages' what you consider to be a bad practice. Instead it provides a useful thing that could be misused by bad programmers.
We shouldn't be designing the language so that it can't be misused by bad programmers - instead we should be designing it so that competent programmers have the tools that they want.
And yes, not everyone will need/want this piece of functionality, but for the people who do want it, saying that they can't have it because it might be misused seems illogical to me.
cheers
Dan
But I don't see how this RFC 'encourages' what you consider to be a bad
practice. Instead it provides a useful thing that could be misused by bad
programmers.
To clarify, programmers are not 'bad'. Their implementation choices,
though, may lead to ambiguous, unintelligible, or unmaintainable code.
If there are examples where this support would lead to poor choices, I've
not recognized them. But, Marco listed the cases I think would benefit from
this support.
+1
Hi,
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehintThis feature is developed to provide missing functionality which is needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.
I just wished a few weeks ago I was able to typehint that. Actually I
even tried just to lern it doesn't work.
It's a unit test helper method to make a method on an object public,
signature:
protected function makeMethodPublic(object $obj, string $methodName):
ReflectionMethod
So, I can come up with exactly one (to me) useful case, but it's
arguable not "that important" and I certainly wouldn't and didn't add an
is_object check for this, so there goes my priority for it.
thanks,
- Marus
Hi Michal!
First of all, many thanks to you and Dan for pushing this forward. It is
indeed a very needed and long due addition to the engine.
I just wanted to clear up the use-case scenarios for everyone in here that
keeps stating that this will lead to bad code.
It is very unlikely to type-hint "object" inside your business domain.
Where this functionality is useful is any of the following (with examples):
- generic hydrators/property access (these exist, and they are widely used
inside form components)
class SillyLibraryHidrator
{
public function hydrate(object $object, array $someData)
{
// pseudo:
foreach ($objectReflectionProperties as $p) {
$p->setValue($object, $someData[$p->getName()]);
}
}
}
- serializers - also widely used, can generally tell them to produce an
object of a certain type. Consumers would then wrap it, and use a more
specific type-hint
interface JsonSerializer
{
public function serialize(object $object) : string;
public function deSerialize(string $data, string $className) : object;
}
- identity maps - typically part of ORMs
interface IdentityMap
{
public function add(string $id, object $object) : void;
public function getId(object $object) : ?string;
public function getObject(string $id) : ?object;
}
- code generators
interface WrapThingIntoAProxy
{
public function wrap(object $object) : object;
}
- instantiation logic for generic factories
interface AGenericFactory
{
public function create(array $data, string $className) : object;
}
- table data gateways/repositories
interface TableDataGateway
{
public function fetchById(array $identifier) : ?object;
}
These are just some of the examples that get direct benefit from this sort
of type-hint, or at least the scenarios that I work with on a daily basis.
Please don't tell me that I have to get back to is_object()
, because:
- it is implicitly part of the implementation, and not part of the
reflectable signature AS IT SHOULD BE - it is more code for me to test
- I cannot throw a TypeError myself, if a non-object is given (TypeError
can't be instantiated in userland, AFAIK), and every time I have to design
custom exceptions (also to be tested/documented) - this way is actually faster than a manual
is_object()
check - intent is conveyed to the consumer directly, and not via documentation
docblock - allows for explicit nullability, yet splitting object/non-object APIs
- many library-level codebases rely on generic code that doesn't know
about one specific type, but just about "objects"
The alternative is going with full generics, but that's not viable for now.
This additional type hint is pretty much covering the scenarios above in a
very approachable way.
Greets,
Marco Pivetta
On Sun, Oct 23, 2016 at 12:39 AM, Michał Brzuchalski <michal@brzuchalski.com
wrote:
Hi all,
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehintThis feature is developed to provide missing functionality which is needed
and quite easy to introduce.
There are many people which I've talked about the benefits of this
functionality.For those who doesn't like the idea and think they won't need neither use
it rather than just saying 'no' they
please say why other people who want to use that parameter type are wrong,
for wanting to do that.If there is anything left to discuss, please comment.
Thanks to @Danack for drafting.
regards / pozdrawiam,
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com
Hi,
Michał Brzuchalski wrote:
I would like to initiate discussion for Object typehint RFC
https://wiki.php.net/rfc/object-typehint
I like this proposal. We already have an object type internally for the
same reasons (functions acting on a generic object), so it makes sense
to extend this to userland which may want to do the same kinds of things.
One potential benefit is that functions can be more generic. I imagine
there's some functions out there typed against \stdClass which could
really accept any object if given the option.
Best of luck.
Andrea Faulds
https://ajf.me/