Hey Anthony,

There's a lot here, so I'm only going to address a few things.

It sounds to me like you haven't tried to use decorators for any complex
logic. Making it type equivalent leads to very vebose code. And a PITA

I actually have used both Decorators and Proxies (it's cousin) a number of times and some in complex situations (these are all ZF2) http://git.io/HdRe6g (Zend\Di), http://git.io/6EGv4Q (Zend\ServiceManager), and http://git.io/DhXDFA (Zend\Db Sql Abstraction), all that aside ...

to write. This is one of the reasons that traits are so heralded.
Because problems that are easy to solve with decorators (in general) are
difficult to solve with PHP, so people wind up writing copy/paste

If what you're trying to do is decorate an instance of a particular concrete type, the basic structure/foundation for creating a Decorator (as defined by wikipedia), can be achieved in PHP with about 3 lines of code:

class FooDecorator extends Foo {
    protected $subject;
    public function __construct(Foo $foo) {
        $this->subject = $foo;
        foreach (get_object_vars($foo) as $n => $v) {
            $this->{$n} =& $foo->{$n};
        }
    }
}

At this point, any instance of new Foo is statefully and type equivalent to new FooDecorator($foo). Now, you're free to add in your custom decoration logic, overridden methods, additional methods, new interfaces, etc. An instance of FooDecorator can be used an any place an instance of Foo would have been used. i.e., it's bound to the Foo context.

Let's get one thing clear here. It's not a LSP check. In that exact
example it is. But in general, it also prevents the LSP valid:

interface foo { public function bar(array $a); }
class Bar implements Foo { public function bar($a); }

That's 100% in compliance with LSP. Yet it's disallowed. The reason is
that interfaces are not primarily a LSP enforcer. They are primarily a
contract enforcer. LSP is a usual side-effect, but it's not a guarantee.

I'll give you this one.

That is an example of contravariance of method arguments, which I'd argue should probably be allowed (if it's not that expensive to do so). PHP does not specifically say it or define type sets, but one would assume that "no type required" should mean "all types" which technically might include "array".

And I don't need to resort to duck typing for it to work. All I need is
the ability to decorate at will. I'm not talking about nuking the
meaning of the interfaces (as they'd be proxied to). But more just

We're going to have to disagree on the "meaning of interfaces". Interfaces are a foundational element of a class based type hierarchy. If you want Interfaces without them being in an instance type hierarchy, I'm not sure what you call that; but it's not an Interface. The decisions made in the PHP group around the class type system more closely resemble those made by Java and C#.

Concerning your code snippets above.

It sounds like you want to dynamically build classes and methods, on the fly, or you want a magical subclass that is free from the current rules of is_a, instanceof, etc.

Put another way, some developer somewhere built a system and has a method signature like

class Controller {
   public function dispatch(Dispatchable $dispatchable) { ... }
}

and they have provided the Dispatchable interface. But you want to take any old object that does not implement Dispatchable and be able to modify it on the fly to bypass his type check in his type check in the method signature of his dispatch().

to solve this problem. I'm talking about runtime composability of
functionality. Not compile time. I want to be able to construct my
objects from other interactions (like database settings), not just be
limited to having to copy/paste for everything.

That's just crazy talk right there! ;)

composing functionality != composing types

In PHP (currently, as anything could change), is_a, instanceof and method type signatures are used by people who believe in a class based type inheritance system and the system of checks built around that.

Your proposal attempts to change that such that special types can be exempt from the type checking rules for the purpose of a particular pattern (Decorator). I've personally never had a problems with decorating, so it is hard for me to envision the system you are building where Decorators are a problem.

-ralph






--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to