AW: AW: PDM Meeting Notes

php.internals

Matthias Pigulla

20 years ago
Now that was a quick reply :)
> Also known as runtime inheritance, or late binding. It's not a new > thing, we have it today. The discussion was about whether to > have a way
... That is, one can write if (...) class A extends X {} else class A extends Y {} right now? Seriously ;)? Every now and then I'm surprised what weird sort of stuff is allowed in PHP :), but most probably you don't really want to write this sort of code in the first place? ;)
> Just like any other signature in an instance, it tells anything that > implements the interface that it must have a constructor and that > constructor must meet the definition in the interface. Useful for > object factories. In most cases you don't want to force a specific > constructor in which case you wouldn't specify it in the > interface, but > I see no reason why you shouldn't be allowed to specify it > there if you > want to.
The point is that interfaces are nothing you could anything with - that is, if you have "something" that implements an interface, it has already been constructed. You never construct instances through an interface (you would have to choose an implementation, the interface isn't one)... I just cannot explain it in a better way ;) It's somewhat similar to that you cannot make static calls on interfaces. Maybe someone could explain what they intend to use it for and what they suspect it to do ;)? -mp.

Rasmus Lerdorf

20 years ago
Matthias Pigulla wrote:
> Now that was a quick reply :) > >> Also known as runtime inheritance, or late binding. It's not a new >> thing, we have it today. The discussion was about whether to >> have a way > ... > > That is, one can write > if (...) class A extends X {} else class A extends Y {} > right now? Seriously ;)? > > Every now and then I'm surprised what weird sort of stuff is allowed in > PHP :), but most probably you don't really want to write this sort of > code in the first place? ;)
Well, or do a conditional include or an include_once and you end up having to do late binding too. It doesn't have to be as weird as your example, but yes, that works too.
>> Just like any other signature in an instance, it tells anything that >> implements the interface that it must have a constructor and that >> constructor must meet the definition in the interface. Useful for >> object factories. In most cases you don't want to force a specific >> constructor in which case you wouldn't specify it in the >> interface, but >> I see no reason why you shouldn't be allowed to specify it >> there if you >> want to. > > The point is that interfaces are nothing you could anything with - that > is, if you have "something" that implements an interface, it has already > been constructed. You never construct instances through an interface > (you would have to choose an implementation, the interface isn't one)... > I just cannot explain it in a better way ;) It's somewhat similar to > that you cannot make static calls on interfaces.
I don't see why you can't specify that a class definition must have a constructor. Obviously the constructor is not for the interface itself. -Rasmus

Jochem Maas

20 years ago
Note: this post contains a 'complaint' but its not aimed at any one in particular, especially not Rasmus as he doesn't give the impression of being much of an OO proponent at heart, and because he repeatly seems to err on the side of practicality and caution (as opposed to correctness for correctness-sake). Rasmus Lerdorf wrote:
> Matthias Pigulla wrote: >
...
>> >> The point is that interfaces are nothing you could anything with - that >> is, if you have "something" that implements an interface, it has already >> been constructed. You never construct instances through an interface >> (you would have to choose an implementation, the interface isn't one)... >> I just cannot explain it in a better way ;) It's somewhat similar to >> that you cannot make static calls on interfaces. > > > I don't see why you can't specify that a class definition must have a > constructor. Obviously the constructor is not for the interface itself.
so I can only assume that the ability to declare ctor signatures have been left in because they do no harm regardless of whether it is 'correct'. so what was the harm in leaving in the ability to declare interface methods as protected (or even private)? ctor declarations in interfaces are just as wrong as protected method declarations (or static method declaration - although they seem to be allowed also - I can't remember if this was always allowed or whether this was reinstated at some point) according to the 'fundamental truth' regarding interfaces (they only make sense in a object context) that has been repeated here many times over. bottom line I am begging for consistency and easy of use: please reinstate the ability to be able to declare something like: interface ImCrazy { abstract static protected function __construct(CrazySettings $s, CrazyView $v); } and if not then I'd be much obliged if someone could point out why non-correct non-harmful ability has been added with regard to interfaces and another equally non-correct non-harmful ability has been removed. understanding why goes along way to acceptance - which boils down to public perception issues once again. rgds, Jochem ** ofcourse if something is technically impossible at the php/zend engine level or if its a very hard to implement edge case situation I can conceed that the break/change/whatever may well have to occur for the sake of practicality/maintainability at a deeper level. making such reasoning clear to lesser mortals is still highly recommended in order to mitigate unnecessary irritation on both sides of the field.

Christian Schneider

20 years ago
Jochem Maas wrote:
> so I can only assume that the ability to declare ctor signatures have > been left in because they do no harm regardless of whether it is > 'correct'.
If I remember correctly then one reason to have constructor signatures is for object factories: You specify that an object to be created by a specific factory has to follow certain constructor rules. I see nothing wrong with that, it is part of a public interface of a class and hence one should be able to specify it in an interface.
> abstract static protected function __construct(CrazySettings $s, > CrazyView $v);
Abstract is purely redundant here as interfaces never implement a function. If on the other hand you mean that classes _implementing_ this interface have to declare those methods as abstract then I don't see how anyone could actually use this interface as no non-abstract class could implement these functions in the interface. Static doesn't really make sense as interfaces as object instance related. As far as protected and private go I have less strong of an opinion but I understand the point of view that interfaces describe the _public_ interface of an object, everything else are implementation details. - Chris

Ants Aasma

20 years ago
Christian Schneider wrote:
>> abstract static protected function __construct(CrazySettings $s, >> CrazyView $v);
<snip>
> Static doesn't really make sense as interfaces as object instance related.
Well actually the constructor is implicitly a static function too. The whole allowing/disallowing constructor in interfaces question is in principle exactly the same as allowing static methods in interfaces. Anyway, I see only one use case for interface constructors: interace IConstructableFromBananas { function __construct(Bananas $b); } function thingsThatUseBananasFactory($className) { $class = new ReflectionClass($className); if (!$class->implementsInterface("IConstructableFromBananas")) { trigger_error("$className doesn't implement IConstructableFromBananas", E_USER_ERROR); } return new $className(BananaFactory::getBananas()); } I'm not so sure whether this is useful to anyone, but I don't see it hurting anyone either. Ants

Jochem Maas

20 years ago
Christian Schneider wrote:
> Jochem Maas wrote: > >> so I can only assume that the ability to declare ctor signatures have >> been left in because they do no harm regardless of whether it is >> 'correct'. > > > If I remember correctly then one reason to have constructor signatures > is for object factories: You specify that an object to be created by a
using an object factory its quite feasable under certain conditions to make the ctor protected to force the use of the factory - the same applies to singleton implementations. hence I don't that a ctor is by its definition public - although, granted, in the normal case it usually so.
> specific factory has to follow certain constructor rules. I see nothing > wrong with that, it is part of a public interface of a class and hence > one should be able to specify it in an interface. > >> abstract static protected function __construct(CrazySettings $s, >> CrazyView $v); > > > Abstract is purely redundant here as interfaces never implement a > function. If on the other hand you mean that classes _implementing_ this > interface have to declare those methods as abstract then I don't see how > anyone could actually use this interface as no non-abstract class could > implement these functions in the interface.
right - I merely meant that the 'abstract' keyword was harmless and could safely be ignored by the engine if used in this context.
> > Static doesn't really make sense as interfaces as object instance related.
that is a matter of consensus (if the accepted software design paradigms change that may very well be considered bullshit in the future) - is there any solid technical reason that the ability to declare an interface method as static? if not then why change the behaviour? (not to mention that it happened in a minor version - going from 'working' to E_FATAL is a rather drastic change for a minor version upgrade).
> > As far as protected and private go I have less strong of an opinion but > I understand the point of view that interfaces describe the _public_ > interface of an object, everything else are implementation details.
I understand the point of view as well, I understand it very well thanks. but I'd like to throw back an argument often used by core developers: 'if you don't like it you don't have to use it' So rather than forcing me to change my previously working code just don't used protected/private/static in _your_ interface declarations. and if you ('you' in general!) really really must impose such purism then either impose it from the start (shitty argument I realise!) or at least let me determine _when_ I fix my code (rather than being _forced_ to stay late at work and not be able to see my son - which has happened to be my reality with respect to abitrary changes in php on more than one occasion) byt giving me an E_STRICT rather than an E_FATAL, an E_FATAL I have to fix otherwise i lose my client, with an E_STRICT I can go home and worry about it tomorrow. AND BESIDES: there is is nothing in the word 'interface' that implies the concept of public - going back to your own factory example - its very handy to be able to allow the the actual factory to conditionally call (or trigger the calls to) certain methods on the objects its generating/creating that are only relevant to the setup/init of said objects - imho the neatest way is to use interfaces, and the neatest way to stop anyone from using the relevant method once the object has been created and returned to the callee is to make it protected (this assumes, in the simplest case, that the factory is also the base class for all the classes of the objects it produces - which is not an impossibility).

Marcus Börger

20 years ago
Hello Jochem, Wednesday, November 23, 2005, 6:52:17 PM, you wrote:
> Christian Schneider wrote: >> Jochem Maas wrote: >> >>> so I can only assume that the ability to declare ctor signatures have >>> been left in because they do no harm regardless of whether it is >>> 'correct'. >> >> >> If I remember correctly then one reason to have constructor signatures >> is for object factories: You specify that an object to be created by a
> using an object factory its quite feasable under certain conditions to > make the ctor protected to force the use of the factory - the same applies > to singleton implementations.
> hence I don't that a ctor is by its definition public - although, granted, > in the normal case it usually so.
>> specific factory has to follow certain constructor rules. I see nothing >> wrong with that, it is part of a public interface of a class and hence >> one should be able to specify it in an interface. >> >>> abstract static protected function __construct(CrazySettings $s, >>> CrazyView $v); >> >> >> Abstract is purely redundant here as interfaces never implement a >> function. If on the other hand you mean that classes _implementing_ this >> interface have to declare those methods as abstract then I don't see how >> anyone could actually use this interface as no non-abstract class could >> implement these functions in the interface.
> right - I merely meant that the 'abstract' keyword was harmless and could safely > be ignored by the engine if used in this context.
>> >> Static doesn't really make sense as interfaces as object instance related.
> that is a matter of consensus (if the accepted software design paradigms > change that may very well be considered bullshit in the future) - is there any > solid technical reason that the ability to declare an interface method as > static? if not then why change the behaviour? (not to mention that it happened > in a minor version - going from 'working' to E_FATAL is a rather drastic change > for a minor version upgrade).
>> >> As far as protected and private go I have less strong of an opinion but >> I understand the point of view that interfaces describe the _public_ >> interface of an object, everything else are implementation details.
> I understand the point of view as well, I understand it very well thanks. > but I'd like to throw back an argument often used by core developers: > 'if you don't like it you don't have to use it'
> So rather than forcing me to change my previously working code just don't used > protected/private/static in _your_ interface declarations. and if you ('you' in general!) > really really must impose such purism then either impose it from the start (shitty > argument I realise!) or at least let me determine _when_ I fix my code > (rather than being _forced_ to stay late at work and not be able to see my son - > which has happened to be my reality with respect to abitrary changes > in php on more than one occasion) byt giving me an E_STRICT rather than an E_FATAL, > an E_FATAL I have to fix otherwise i lose my client, with an E_STRICT I can go home > and worry about it tomorrow.
> AND BESIDES: there is is nothing in the word 'interface' that implies the concept > of public - going back to your own factory example - its very handy to be able to > allow the the actual factory to conditionally call (or trigger the calls to) > certain methods on the objects its generating/creating that are only relevant to the > setup/init of said objects - imho the neatest way is to use interfaces, and the neatest > way to stop anyone from using the relevant method once the object has been created and returned > to the callee is to make it protected (this assumes, in the simplest case, that the factory > is also the base class for all the classes of the objects it produces - which is not an > impossibility).
Whike speaking of private or protected interface functions everyone here seems to do the same wrong assumptions. Regarding private the problem is that provate members are not visible outside of a scope. Hence a class that implements an interface with a private method will always have on abstract function. So Neither the class itself nor any of its child can be instanciated. The only usage left is to have a way to introduce static classes. But luckily we are not Java and hava use for that. And even if we had we could do it with "static class ... { ... }". Now coming to protected members in interfaces the problem is that it is always possible to increase visibility in derived classes. Thus protected in interfaces doesn't give you anything because we have no compile time function call generation for interface based invocation. Actually in PHP none of the last two sentences makes any sense whatsoever. What you might want to enforce here ist that having a visibility declaration makes it impossible to change a functions visibility thus you suddenly make the visibility part of the inherited signature of a function. Doing so would make PHP code suddenly much harder to devlop because it would be very hard to see why the behavior of basic rules suddenly changes. Allowing ctors in interfaces simply reinforces a rule we disabled especially for ctors. Thus all normal rules apply and nothing new has to be learned. Which is imo even easier then what we have toay where you have to learn that interfaces *do not* allow to enforce signatures on ctors. Best regards, Marcus