rfc:callable-interfaces

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
Last revisionBoth sides next revision
rfc:callable-interfaces [2016/04/06 11:32] – CS (brackets on same line, improves readability ocramiusrfc:callable-interfaces [2016/04/12 10:11] – Retiring RFC due to incompatible object -> function semantics mixup ocramius
Line 4: Line 4:
   * Author: Ben Scholzen, mail@dasprids.de   * Author: Ben Scholzen, mail@dasprids.de
   * Author: Marco Pivetta, ocramius@gmail.com   * Author: Marco Pivetta, ocramius@gmail.com
-  * Status: Draft+  * Status: Retired
   * First Published at: http://wiki.php.net/rfc/callable-interfaces   * First Published at: http://wiki.php.net/rfc/callable-interfaces
  
Line 15: Line 15:
 ===== Proposal ===== ===== Proposal =====
  
-PHP already has a way to define objects that act as functions. That mechanism is the **_****_invoke** magic method, which is widely used in libraries and frameworks. In addition to that, **Closure** already implements **_**_****invoke**.+PHP already has a way to define objects that act as functions. That mechanism is the **_****_invoke** magic method, which is widely used in libraries and frameworks. In addition to that, **Closure** already implements **_****_****invoke**.
  
-**_**_****invoke** already works quite well: with this proposal, generic *callable* arrays, functions and objects will be usable as if they implemented a matching interface:+**_****_****invoke** already works quite well: with this proposal, generic *callable* arrays, functions and objects will be usable as if they implemented a matching interface:
  
 <code php> <code php>
Line 92: Line 92:
 <code php> <code php>
 function passAParameterToAPhpFunction(callable $callable, $expectedParameterInterface) { function passAParameterToAPhpFunction(callable $callable, $expectedParameterInterface) {
 +    if (! $expectedParameterInterface->isCallableInterface()) {
 +        passParameter($callable);
 +        
 +        return;
 +    }
 +    
     if (! $expectedParameterInterface->matches($callable)) {     if (! $expectedParameterInterface->matches($callable)) {
          throw new TypeError('Expected X, got Y');          throw new TypeError('Expected X, got Y');
Line 97: Line 103:
          
     if (! is_object($callable)) {     if (! is_object($callable)) {
-        $callable = wrapInCompatibleSignatureClosure($callable);+        $callable = wrapInCompatibleAnonymousClass($callable);
     }     }
          
Line 103: Line 109:
 } }
 </code> </code>
 +
 +===== Still Open for Discussion =====
 +
 +How will **instanceof** behave, when asked for a type-check against **callable**?
 +
 +<code php>
 +interface RegisterUser {
 +    public function __invoke(Username $username) : UserRegistration;
 +}
 +
 +interface DeleteUserRegistration {
 +    public function __invoke(Username $username) : UserRegistration;
 +}
 +
 +$register = function (Username $username) : UserRegistration {
 +    return new UserRegistration(...);
 +};
 +
 +var_dump($register instanceof DeleteUserRegistration); // true? false? possibly want to keep current semantics here.
 +</code>
 +
 +===== Retired =====
 +
 +This RFC has been retired. Reason for that is that PHP currently (Version 7.0~7.1) allows applying function semantics to objects via the **_****_invoke** magic methods. Allowing the opposite would mix the domain of functions and objects in ways that are very hard to disentangle, and it would needlessly complicate the language semantics.
 +
 +While it is unfortunate that migration to type-safe callables (https://wiki.php.net/rfc/typesafe-callable) would require some interface rewrites, that is indeed the correct solution, as it keeps the uni-directionality between object and function semantics.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
rfc/callable-interfaces.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1