rfc:protocol_type_hinting

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:protocol_type_hinting [2013/06/26 16:21] – Add significant use-cases ircmaxellrfc:protocol_type_hinting [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 3: Line 3:
   * Date: 2013-06-25    * Date: 2013-06-25 
   * Author: Anthony Ferrara <ircmaxell@php.net>   * Author: Anthony Ferrara <ircmaxell@php.net>
-  * Status: Draft +  * Status: Withdrawn 
   * First Published at: http://wiki.php.net/rfc/protocol_type_hinting   * First Published at: http://wiki.php.net/rfc/protocol_type_hinting
  
Line 89: Line 89:
 } }
 class StaticLogger { class StaticLogger {
-    public static function log($message);+    public static function log($message) { /* blah */ }
 } }
 class OtherLogger { class OtherLogger {
-    public static function log($message, $bar);+    public static function log($message, $bar) { /* blah */ }
 } }
 Bar::foo(new FileLogger); // Good! Bar::foo(new FileLogger); // Good!
Line 234: Line 234:
  
 It also solves the triangular dependency problem since the sender never needs to explicitly require the dependency. That can be left for an off-line check (or a test), reducing the amount of and need for dependency resolving tools for the purpose of common interfaces... It also solves the triangular dependency problem since the sender never needs to explicitly require the dependency. That can be left for an off-line check (or a test), reducing the amount of and need for dependency resolving tools for the purpose of common interfaces...
 +
 +==== Trait Typing ====
 +
 +Currently, traits do not allow for specifying of typing information. And this is a good thing (it is by design).
 +
 +However, there are many times where we may wish to infer that the functionality presented by a trait is present in an object. An example would be Zend Framework's [[https://github.com/zendframework/zf2/blob/master/library/Zend/EventManager/ProvidesEvents.php|ProvidesEvents Trait]]. It basically looks like this:
 +
 +<file php ProvidesEvents.php>
 +<?php
 +namespace Zend\EventManager;
 +trait ProvidesEvents {
 +    protected $events;
 +    public function setEventManager(EventManagerInterface $events) { /* snip */ }
 +    public function getEventManager() { /* snip */ }
 +}
 +?>
 +</file>
 +
 +As the current system stands, classes that use the trait need to also implement a separate interface to get the message of the behavior across to the receiver that it supports events.
 +
 +With Structural Type Hinting, we can instead hint against the trait directly, which would require a class with the same public API that the trait provides, //irrespective of if it is actually using the trait or not//.
 +
 +<file php RequiresEvents.php>
 +<?php
 +function triggerEvent(<Zend\EventManager\ProvidesEvents> $target, $eventName) {
 +    $target->getEventManager()->trigger($eventName, $target);
 +}
 +?>
 +</file>
 +
 +If the object uses the trait, it will always resolve. But it also gives other classes which implement the same public API the ability to resolve the trait.
 +
 +==== The Place For Current Interfaces ====
 +
 +Why not just get rid of current interfaces and change their behavior to Structural typing (besides the MASSIVE BC break)?
 +
 +In practice there are two reasons (times) that you would use an interface:
 +
 +1. To provide typing information about a domain object (or a value object). This is where the typing actually means something specific to the application.
 +
 +An example would be a User object in an application. You may want to have a UserInterface which the User class implements, because the interface actually implies that the object *belongs* to the domain. It's providing *type* information about the object.
 +
 +2. To provide functionality information about a object. This where the interface really just describes the functionality of the object.
 +
 +An example would be a service which encodes a password. There's no special typing information needed. The interface simply provides a semantic way of identifying the API of the service. So it's not really providing *type*, but more capability.
 +
 +With this new proposal, Type information would still be implemented via traditional interfaces. But capability information would use Structural Typing.
 +
 +So there is very much a place for both to live side-by-side in the same language.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
rfc/protocol_type_hinting.1372263665.txt.gz · Last modified: 2017/09/22 13:28 (external edit)