Hi, David. :)

> First of all, I thank you again for your comments. Do not believe we do
not consider them. Actually, your argument about the Liskov substitution
principle got me thinking the last 24 hours (hence my lack of quick reply
:) ) Your comments are always welcome as they force us to think harder
about what we are doing and in the end, they lead to a better standard.

I know you all take these discussions into consideration, what I meant was
simply that I had already spoke my heart and that I probably wouldn't have
anything else to add =).

Since you've replied to my concerns about LSP, let me address it too.

> Liskov Substitution Principle does not state that "S" that is a subtype
of "T" can be replaced with "S' " that is also a subtype of "T".

It kind of does, though a simple syllogism.

1) ContainerInterface is not an implementation, but is a type nonetheless.
2) Any implementation of ContainerInterface is a subtype of
ContainerInterface.
3) LSP dictates I should be able to use any (variable S) subtype of
ContainerInterface wherever a ContainerInterface is acceptable, *without
altering any of the desirable properties of that program.*
4) Therefore, subtypes of ContainerInterface should not differ amongst
themselves in how they affect* the desirables properties of my program*.
Conclusion: If my program accepts S, it's under no obligation of accepting
S'. But if it accepts T, it should accept both S and S'.

Overall, I agree that solution (1) is better than the current wording. I'm
not sure if I agree with the other things that we have being disagreeing
about (mainly, if this is a in-scope or out-of-scope issue), and I have
nothing new to add in that aspect.

Even though I have a feeling I'm outnumbered in my opinion, this has been a
very interesting conversation. Thank you kindly for taking the time to
respond each single time :)

2016-11-10 9:33 GMT-02:00 David Négrier <[email protected]>:

> Hi Pedro,
>
> First of all, I thank you again for your comments. Do not believe we do
> not consider them. Actually, your argument about the Liskov substitution
> principle got me thinking the last 24 hours (hence my lack of quick reply
> :) ) Your comments are always welcome as they force us to think harder
> about what we are doing and in the end, they lead to a better standard.
>
> So... what about the Liskov Substitution Principle. Are we violating it?
>
> From Wikipedia: *Liskov's notion of a behavioral subtype defines a notion
> of substitutability for objects; that is, if S is a subtype of T, then
> objects of type T in a program may be replaced with objects of type S
> without altering any of the desirable properties of that program*
>
> Liskov Substitution Principle does not state that "S" that is a subtype of
> "T" can be replaced with "S' " that is also a subtype of "T".
>
> Also, we are subtyping an interface (not a class). To violate the LSP, the
> implementation must be "semantically different" from what is described in
> the documentation of the interface. So actually, the less we put in the
> documentation and the less we are likely to violate the LSP. In that
> regard, I'm leaning (like Matthew) towards solution 1 (let's simply remove
> the whole 2 sentences and let's not specify at all that 2 successive calls
> to "get" SHOULD return the same value. We simply don't care).
>
> As such, I'm willingfully lowering the expectation a user can have on the
> interface (the interface does not say much about what a container is).
> Therefore, I'm putting the "burden" of checking that the container he is
> choosing actually does what he expects to do
> <http://softwareengineering.stackexchange.com/questions/170925/does-liskov-substitution-principle-also-apply-to-classes-implementing-an-interfa>
>  (and
> is properly configured) But this is alright.
>
> The more I think about it, the more I believe this is the right thing to
> do.
>
> For the sake of the example, let's make a contraposition and let's try a
> "reductio ad absurdum".
>
> If we want ANY implementation to be replaceable by ANY other
> implementation, we obviously need to define that 2 successive calls to
> "get" MUST return the same value.
> But that's not enough. Currently, the spec states that "A call to get can
> return anything (a *mixed* value)"
>
> We would need to rewrite that as: "Containers implementing this spec MUST
> be able to return anything (any possible *mixed* value returnable by
> PHP)".
>
> At this point, we are actually dictating that the container
> implementations MUST support a way to define entries via a callback
> (because it is really the only way you can return any possible mixed
> value). For instance, it would be very hard for a container based on
> configuration alone to be able to return a resource, or a generator (which
> are valid return values).
>
> Another solution could be to restrict the allowed return types (for
> instance: a container MUST only return objects, or a container MUST only
> return objects and scalars). If we write this, then Pimple and all
> containers supporting the creation of services via a factory (i.e. most
> containers out there) need to be rewritten to actually prevent the return
> of other values.
>
> At this point, maybe you start to realize that having strong expectations
> on the behaviour of a container is actually "dictating" how it should work
> internally.
>
> If you need yet another argument, let's have a look at PSR-6 and the
> values that are allowed to be passed: http://www.php-fig.org
> /psr/psr-6/#data
>
> PSR-6 states that: *Implementing libraries MUST support all serializable
> PHP data types*
> PSR-6 does not state that: *Implementing libraries MUST NOT support PHP
> data types that are not serializable*
>
> Now, let's have a look at Stash's Ephemeral driver (
> https://github.com/tedious/Stash/blob/master/src/Stash/Driv
> er/Ephemeral.php)
> This driver is essentially storing data in an array. This means that I can
> store a database connection or a GD image resource in this array (these are
> not serializable). It is absurd but it will work. Of course, if I do this,
> I cannot expect to switch from the Ephemeral driver to a MemcacheDriver
> later. Is it a problem with the Ephemeral driver? I don't think so. Does
> the Ephemeral driver violates the LSP? Nope. The Ephemeral driver is simply
> extending what is allowed by the PSR-6 and the user is having wrong
> expectations that these extended features are available in all
> implementations.
>
>
> To sum it up, we are having this debate because counter-intuitively,
> PSR-11 does not define what a container is. By not defining it, it leaves
> the user *in charge* of choosing a container that answers its needs. We
> could of course go the other way and define precisely what a container is,
> but containers are so different out there that we would be excluding most
> of them by doing so. If we go that way, we need a good reason to do it. But
> so far, I don't see a real use case good reason. Our experience with
> container-interop has shown us that being very "liberal" about the
> definition of a container is not a problem. We can still have practical use
> cases (like Zend-Expressive or mnapoli's Invoker). So I'm keeping my
> opinion (and leaning towards Solution 1)
>
> ++
> David.
>
>
> Le mercredi 9 novembre 2016 13:23:33 UTC+1, Pedro Cordeiro a écrit :
>>
>> Hi, Matthew! Thanks for replying :)
>>
>> Larry and I presented a few cases where the framework relies on its
>> components having a shared instance, instead of exclusive ones. Every
>> framework component that fetches services that handles connections, IO
>> sockets, in-memory caches, and others HAVE to be given shared instances.
>> Being fed new (empty) in-memory caches every time is crazy, right? :) If
>> you could address how we can deal with these cases with factory-only
>> containers, maybe it could be clearer to me.
>>
>> I don't really agree that most services are only fetched once by the
>> framework -- an event dispatcher (that traditionally has an in-memory
>> registry of listeners that must be shared) could be fetched various times
>> by various different components - to register new listeners or to simply
>> dispatch events. It would depend on the framework here. Maybe a
>> microframework tends to fetch less, but a fullstack framework could really
>> differ in that aspect.
>>
>> Like I said before, I would agree that it's an application/configuration
>> issue if all containers were interoperable on a behavior level. If the user
>> had misconfigured a container to act as factory for a specific service,
>> where it should be retrieving shared instances, ok, that's a bug, not this
>> PSR's fault. However, once we decide to allow factory-only containers, we
>> define that there is no way to configure these containers properly for
>> components that need shared instances (such as the ones I mentioned
>> previously). Hence, we have a compatibility issue.
>>
>> Again, choosing the right containers for my use is not a
>> configuration/application issue. PSR-11's goal SHOULD be container
>> interoperability. Which means containers should agree on a minimum behavior
>> to be interoperable. If we need to code to specific implementations, than a
>> standard is not needed at all.
>>
>> I won't dwell any more into this issue, because I feel like I'm bashing
>> the same key over and over again. I feel like I've said all I had to say in
>> that aspect, and I only have the best intentions in mind for this PSR. If
>> you all feel like it's not a big issue, then let's move on. I do feel like
>> it's a big issue, though.
>>
>> Em terça-feira, 8 de novembro de 2016 17:54:08 UTC-2, Matthew Weier
>> O'Phinney escreveu:
>>>
>>>
>>>
>>> On Tue, Nov 8, 2016 at 6:55 AM, Pedro Cordeiro <[email protected]
>>> > wrote:
>>>
>>>> Hi, Matthew!
>>>>
>>>> I understand everything you said. About the configuration
>>>> responsibility, this PSR's scope and the fact that it's coherent to have
>>>> non-shared services in some contexts. I never disagreed with any of that.
>>>>
>>>> I'll try to be more objective here.
>>>>
>>>> Given two containers:
>>>>
>>>> a) "ContainerShared", that implements PSR-11 and ONLY returns shared
>>>> instances, no option to configure non-shared services;
>>>> b) "ContainerFactory", that implements PSR-11 and ONLY returns
>>>> non-shared instances, acts as a factory always.
>>>>
>>>> Do you agree that:
>>>>
>>>> 1) These implementations are perfectly fine PSR-11 implementations, as
>>>> it's phrased right now?
>>>> 2) These implementations are incompatible between themselves for pretty
>>>> much every use case, including zend-expressive, that is currently the most
>>>> successful case of container interoperability?
>>>> 3) The incompatibility between these two containers is not an
>>>> application/configuration issue, but plain lack of interoperability between
>>>> them?
>>>>
>>>> If you agree with (1), (2) and (3), the final question that stands is:
>>>> is it still OK to have container implementations that are NOT interoperable
>>>> implementing an interoperability standard?
>>>>
>>>
>>> I don't agree with your assessment at all.
>>>
>>> I agree with point 1. I don't agree with either point 2 or point 3.
>>>
>>> In the majority of use cases I've encountered, the workflow goes
>>> something like this:
>>>
>>> - Application composes a container.
>>> - Application does some sort of request routing to determine what
>>> service to dispatch
>>> - Application pulls that service from the container and dispatches it
>>>
>>> This means that, regarding point 2, whether or not instances are shared
>>> is typically moot. They are pulled from the container generally once, and
>>> once only, in any given request. (Yes, there are times when multiple
>>> retrieval may happen, particularly in large, event-based applications where
>>> multiple listeners may use the same services.)
>>>
>>> However, this leads to point 3: it's absolutely an
>>> application/configuration issue. You need to choose the container that
>>> suits your application needs and configure it accordingly. The PSR-11
>>> specification is only around *retrieving* services. It is specifically not
>>> detailing how those services are stored within, whether or not the service
>>> MUST return the same instance, etc. The point is that if you have a
>>> container, can you (a) test if the service is present, and then (b)
>>> retrieve it?
>>>
>>> The *behavior* aspect — if the service is shared or not, and how to
>>> configure services in the container — is purposely intended for a future
>>> PSR that covers that aspect.
>>>
>>> For a consumer, they can typehint on ContainerInterface and exercise its
>>> API. They retrieve the service, and do something with it. Whether or not
>>> that service is shared or the correct instance expected will be entirely up
>>> to the container implementation they choose, and how they configure
>>> services in that container. So I disagree with your third point as well.
>>>
>>> <snip>
>>>
>>> If *YOU*, zend-expressive developer, were to develop a truly agnostic
>>>> container consumption implementation based on PSR-11, you'd have to
>>>> document something to the effect of: "while zend-expressive is compatible
>>>> with PSR-11 containers in general, it's not meant to be used with
>>>> factory-only containers. Choose accordingly.". THAT is what strikes me as
>>>> something weird to have.
>>>>
>>>
>>> Honestly, Expressive *does not care*. At the application skeleton level,
>>> we're not working with shared instances; we're working with a router, an
>>> error handler, and whatever middleware we pull from the container. The
>>> question of *shared* services comes up for the *application developer*,
>>> which is why Expressive *provides a choice of containers*: to allow the
>>> application developer to choose the container implementation that suits
>>> their project. As long as that container is compatible with the PSR, it's
>>> compatible with Expressive, plain and simple, because all we do is exercise
>>> its API.
>>>
>>> --
>>> Matthew Weier O'Phinney
>>> [email protected]
>>> https://mwop.net/
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/php-fig/a232b50d-137f-4a74-8500-bd9b67b07a31%40googlegroups.com
> <https://groups.google.com/d/msgid/php-fig/a232b50d-137f-4a74-8500-bd9b67b07a31%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>



-- 

*Pedro Cordeiro*
Produto

Phone: +55 31 3024 1115
<%2B55%2031%203024%200283>

[image: Logo assinatura]
<http://t.rdsv6.net/wf/click?upn=9ID9MxPkUk-2FXCePkr1qGk3jeNsyS6MabLki1WEC2jiXwUuwMLrMuwyQMihLilvGuFQlwqGcwaqcxv14TZBo-2Fkx216CWkoFS-2BFrkKrfuwK-2BVQHJQ1z2pKo2dYIxq5cmilGdRu7bAh5za9wh3RLzO4nA-3D-3D_wKmGSCWlO-2F6J-2FSpm-2BxtvG5JaaAosDe4Q3OV4TyR4tzwOAocQ0H-2BKup9nj5ZrffTGmoFTZ-2FwY-2BiZ62zA9YUETNc69y4PsViv5cHctzYQM9bh8n4o9ivPlzVyx-2BJyllIEnG1Q-2F2tN-2BOSPuz0Nn8uv2ZSfKxBLUbTLKbmGhzSIZRi0PYxNI8DwJc7HKhR0hHwKI8kmuyZfBkzNrxoCmV0NXGSkn3a3WzIqMEkuwdILSgR-2Fm4Yi08v1XJ0ACOgxAjO-2BND8H30UmwWPAPr6joAP3kKuQ6WcA7R-2FTErDPH0l26ly5T8d00DrbMV7fXYAiuL24XcUrHvHs1-2BIk0UWwDs-2F72MMLfB2NOFl6lJHtovPskkuiwYJajeWEJycLVSCkLape6k6LHU-2BSZcF2Uvp2Asye0iUJTldf0eVlnrql-2BA6I-2F6d00ZAiOxLHEVlUTd1ixtgJipaRe0L1jjobMF41uBNJLCRzafhz8q5oziitdm7z7VLEgrZz2klJhql8ltu8q97TK>

<http://t.rdsv6.net/wf/click?upn=9ID9MxPkUk-2FXCePkr1qGk3jeNsyS6MabLki1WEC2jiXwUuwMLrMuwyQMihLilvGuFQlwqGcwaqcxv14TZBo-2Fkx216CWkoFS-2BFrkKrfuwK-2BVQHJQ1z2pKo2dYIxq5cmilGdRu7bAh5za9wh3RLzO4nA-3D-3D_wKmGSCWlO-2F6J-2FSpm-2BxtvG5JaaAosDe4Q3OV4TyR4tzwOAocQ0H-2BKup9nj5ZrffTGmoFTZ-2FwY-2BiZ62zA9YUETNc69y4PsViv5cHctzYQM9bh8n4o9ivPlzVyx-2BJyllIEnG1Q-2F2tN-2BOSPuz0Nn8uv2ZSfKxBLUbTLKbmGhzSIZRi0PYxNI8DwJc7HKhR0hHwKI8kmuyZfBkzNrxoCmV0NXGSkn3a3WzIqMEkuwdILSgR-2Fm4Yi08v1XJ0ACOgxAjO-2BND8H30UmwWPAPr6joAP3kKuQ6WcA7R-2FTErDPH0l26ly5T8d00DrbMV7fXYAiuL24XcUrHvHs1-2BIk0UWwDs-2F72MMLfB2NOFl6lJHtovPskkug8HnNMYMLjg6qWS45zCOIrm0vptTNigLUcaaUyHWLPOZGe0FSmf9PqyBfjwjFw-2F88h7bt2F1L5K-2FcCWvoYbYXvfmpn1s4vRjzgBFGFfMaV4wNfAKPCaPqR75Md-2Flsd-2F7ry86VRGQ2Sc0YQoNvf1REv>*O
site com o maior número de eventos à venda do Brasil!*
<http://t.rdsv6.net/wf/click?upn=9ID9MxPkUk-2FXCePkr1qGk3jeNsyS6MabLki1WEC2jiXwUuwMLrMuwyQMihLilvGuFQlwqGcwaqcxv14TZBo-2Fkx216CWkoFS-2BFrkKrfuwK-2BVQHJQ1z2pKo2dYIxq5cmilGdRu7bAh5za9wh3RLzO4nA-3D-3D_wKmGSCWlO-2F6J-2FSpm-2BxtvG5JaaAosDe4Q3OV4TyR4tzwOAocQ0H-2BKup9nj5ZrffTGmoFTZ-2FwY-2BiZ62zA9YUETNc69y4PsViv5cHctzYQM9bh8n4o9ivPlzVyx-2BJyllIEnG1Q-2F2tN-2BOSPuz0Nn8uv2ZSfKxBLUbTLKbmGhzSIZRi0PYxNI8DwJc7HKhR0hHwKI8kmuyZfBkzNrxoCmV0NXGSkn3a3WzIqMEkuwdILSgR-2Fm4Yi08v1XJ0ACOgxAjO-2BND8H30UmwWPAPr6joAP3kKuQ6WcA7R-2FTErDPH0l26ly5T8d00DrbMV7fXYAiuL24XcUrHvHs1-2BIk0UWwDs-2F72MMLfB2NOFl6lJHtovPskkuh-2FcAWngEps85gZcv1JSt88f2MW6opGq90KNlySvzdU-2Fye89UtpBfv3fUye6Q18GdWjcQkrSLGREh4GUTjQXGm2TY6JDX6BMrWAmqiU-2BRatDqBDMb7o4f0IPHrMBwqWCmc1qGopJBiN5-2FLRBjhg40Gq>
www.sympla.com.br
<http://t.rdsv6.net/wf/click?upn=9ID9MxPkUk-2FXCePkr1qGk3jeNsyS6MabLki1WEC2jiVLI3wuhL5Ti6hw89C0ESCSVJNdh8FfaGqV-2BFmL5HRlzZKExa4qrB0ctNsViB6l8TFdI11l371V56-2Ffz1iwPM-2FaLxM6A0XQGU-2B6JVEDbnNA0Q-3D-3D_wKmGSCWlO-2F6J-2FSpm-2BxtvG5JaaAosDe4Q3OV4TyR4tzwOAocQ0H-2BKup9nj5ZrffTGmoFTZ-2FwY-2BiZ62zA9YUETNc69y4PsViv5cHctzYQM9bh8n4o9ivPlzVyx-2BJyllIEnG1Q-2F2tN-2BOSPuz0Nn8uv2ZSfKxBLUbTLKbmGhzSIZRi0PYxNI8DwJc7HKhR0hHwKI8kmuyZfBkzNrxoCmV0NXGSkn3a3WzIqMEkuwdILSgR-2Fm4Yi08v1XJ0ACOgxAjO-2BND8H30UmwWPAPr6joAP3kKuQ6WcA7R-2FTErDPH0l26ly5T8d00DrbMV7fXYAiuL24XcUrHvHs1-2BIk0UWwDs-2F72MMLfB2NOFl6lJHtovPskkuhalNGqZenIN2ujgLDSs5Ohlft6K9qJu5v-2FZ3QUR1aZ9-2FzqGgwzr01AaKq7A-2FhO998bW0GWIpli0JgybJylzgA2ITDrio-2FSPnUvfYn56sgyWGIEtX1JTsSWBKJ7DZK8go8mcVbmwvX2oitsQJ8jGzKm>

-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/CADuw3E-%3DAvMw1WLE3BPYsLsUiMC5wU50ka6c57hvQ-h0ceVPVw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to