Re: [PHP-DEV] Closures as methods (and Closure::bind)

2010-08-12 Thread Gustavo Lopes
On Wed, 11 Aug 2010 14:57:47 +0100, Johannes Schlüter  
johan...@schlueters.de wrote:



On Wed, 2010-08-11 at 14:38 +0100, Gustavo Lopes wrote:

I've updated the wiki page for Closures with objects extension with
things that are in Proposal A with modifications but are not  
implemented:


http://wiki.php.net/rfc/closures/object-extension#status_as_of_august_10_2010

I propose an implementation of closures stored in properties used as
methods, as in:

$this-prop = function () { ...}
$this-prop();


[...]
I don#t have an opinion on this feature, yet, I like the current
class-based object model as reading code is relatively simple, with this
addition (and the fact that you can create properties on the fly) we
create a powerful tool for really hard to read code.



It's important to understand this is not mere syntactic sugar over

$a = $this-prop;
$a();

or call_user_func($this-prop). It actually allows executing closures in a  
way that fails if the staticness or bound instance of the closure is not  
what was expected.


See the beautiful tree graphs on the wiki page.

--
Gustavo Lopes

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



[PHP-DEV] Closures as methods (and Closure::bind)

2010-08-11 Thread Gustavo Lopes
I've updated the wiki page for Closures with objects extension with  
things that are in Proposal A with modifications but are not implemented:


http://wiki.php.net/rfc/closures/object-extension#status_as_of_august_10_2010

I propose an implementation of closures stored in properties used as  
methods, as in:


$this-prop = function () { ...}
$this-prop();

A few issues that may merit discussion (copied from the wiki page):

- Do we really want to make closures-as-methods have priority over  
__call/__callStatic? On one hand, there's no way to otherwise allow  
closures-as-methods in classes that implement these magic methods, on the  
other one, this breaks BC and makes the magic methods even more  
inefficient – we have to check if there is a method and a property with  
that name.
- Properties are not case-sensitive, hence calling closures-as-methods is  
case-sensitive (contrary to calling regular methods).
- What to do with properties with no visibility? Ignore them (and let fall  
back to __call/__callStatic) or raise error (the implementation in the  
patch raises an error).
- What to do with properties used as methods that are not closures? Ignore  
them or raise an error (the implementation raises an error).
- Should we throw an exception when calling a closure-as-instance method  
that's stored as a static method? Usually, accessing a static property in  
a non static context raises an E_STRICT, but I think may very well be very  
useful, because we can swap instance method implementations on a class  
basis instead of only an instance basis.


I've also updated the bindTo behavior change and document it in the same  
wiki page. Compared to the previous patch I'd sent, this implementation  
has more tests, moves getScope to reflection (a getClosureScopeClass that  
returns a ReflectionClass) and allows binding objects with NULL scope  
(uses a dummy scope instead) instead of silently refusing to bind the  
object.


--
Gustavo Lopes

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



Re: [PHP-DEV] Closures as methods (and Closure::bind)

2010-08-11 Thread Johannes Schlüter
On Wed, 2010-08-11 at 14:38 +0100, Gustavo Lopes wrote:
 I've updated the wiki page for Closures with objects extension with  
 things that are in Proposal A with modifications but are not implemented:
 
 http://wiki.php.net/rfc/closures/object-extension#status_as_of_august_10_2010
 
 I propose an implementation of closures stored in properties used as  
 methods, as in:
 
 $this-prop = function () { ...}
 $this-prop();
 
 A few issues that may merit discussion (copied from the wiki page):

A few more things coming to mind without much thought:

  * What if both a method and a property with the name exist?
  * What about allowing properties with function names as strings or
array($obj_or_class, 'method'), won't that be needed for being
consistent with local variables?
  * In the array($object, 'method') case: What's the scope
for $this?

I don#t have an opinion on this feature, yet, I like the current
class-based object model as reading code is relatively simple, with this
addition (and the fact that you can create properties on the fly) we
create a powerful tool for really hard to read code.

johannes



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



Re: [PHP-DEV] Closures as methods (and Closure::bind)

2010-08-11 Thread Gustavo Lopes
On Wed, 11 Aug 2010 14:57:47 +0100, Johannes Schlüter  
johan...@schlueters.de wrote:



On Wed, 2010-08-11 at 14:38 +0100, Gustavo Lopes wrote:

I've updated the wiki page for Closures with objects extension with
things that are in Proposal A with modifications but are not  
implemented:


http://wiki.php.net/rfc/closures/object-extension#status_as_of_august_10_2010

I propose an implementation of closures stored in properties used as
methods, as in:

$this-prop = function () { ...}
$this-prop();

A few issues that may merit discussion (copied from the wiki page):


A few more things coming to mind without much thought:

  * What if both a method and a property with the name exist?


An existing method has priority over closure-as-method, just like it has  
priority over __call. I implemented what was in the modified proposal A.  
Personally, I think __call should have priority over closure-as-method so  
as to not to break BC.



  * What about allowing properties with function names as strings or
array($obj_or_class, 'method'), won't that be needed for being
consistent with local variables?


Well, you cannot do $a = 'phpinfo'; $a(); as well, so it's consistent  
with that. I think what you refer to would only make sense if that were  
allowed.




  * In the array($object, 'method') case: What's the scope
for $this?


call_user_func(array($object, 'method')) is the same as $object-method(),  
the calling scope is that whatever scope is defined for the closure. The  
value of $this is the object that's bound to the closure; an E_WARNING  
notice is raised if $this !== $object (as mentioned in the proposal).



class A {
public $prop;
}
$a1 = new A;
$a2 = new A;
$a1-prop = Closure::bind(function () { var_dump($this); }, $a2);
call_user_func(array($a1, 'prop'));

gives:

Warning: Closure called as method but bound object differs from containing  
object in ...

object(A)#2 (1) {
  [prop]=
  NULL
}



I don#t have an opinion on this feature, yet, I like the current
class-based object model as reading code is relatively simple, with this
addition (and the fact that you can create properties on the fly) we
create a powerful tool for really hard to read code.



We could forbid using dynamic properties for this functionality, though  
I'd say it's arguably useful.



--
Gustavo Lopes

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



Re: [PHP-DEV] Closures as methods (and Closure::bind)

2010-08-11 Thread Johannes Schlüter
On Wed, 2010-08-11 at 15:29 +0100, Gustavo Lopes wrote:
 
* What about allowing properties with function names as
 strings or
  array($obj_or_class, 'method'), won't that be needed for
 being
  consistent with local variables?
 
 Well, you cannot do $a = 'phpinfo'; $a(); as well, so it's
 consistent with that. I think what you refer to would only make sense
 if that were allowed.

You can. This is valid.

johannes


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



Re: [PHP-DEV] Closures as methods (and Closure::bind)

2010-08-11 Thread Gustavo Lopes
On Wed, 11 Aug 2010 15:37:01 +0100, Johannes Schlüter  
johan...@schlueters.de wrote:



On Wed, 2010-08-11 at 15:29 +0100, Gustavo Lopes wrote:


   * What about allowing properties with function names as
strings or
 array($obj_or_class, 'method'), won't that be needed for
being
 consistent with local variables?

Well, you cannot do $a = 'phpinfo'; $a(); as well, so it's
consistent with that. I think what you refer to would only make sense
if that were allowed.


You can. This is valid.



Oh. I'll change it then.


--
Gustavo Lopes

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



Re: [PHP-DEV] Closures as methods (and Closure::bind)

2010-08-11 Thread Gustavo Lopes
On Wed, 11 Aug 2010 15:37:01 +0100, Johannes Schlüter  
johan...@schlueters.de wrote:



On Wed, 2010-08-11 at 15:29 +0100, Gustavo Lopes wrote:


   * What about allowing properties with function names as
strings or
 array($obj_or_class, 'method'), won't that be needed for
being
 consistent with local variables?

Well, you cannot do $a = 'phpinfo'; $a(); as well, so it's
consistent with that. I think what you refer to would only make sense
if that were allowed.


You can. This is valid.



OK, I know where I got this idea. $a = 'phpinfo'; $a(); is actually the  
only valid case. array callbacks or 'Foo::bar' are forbidden.


In order to be called as instance methods, the closure properties needs to  
have a bound instance -- preferably -- very preferably -- the instance  
where the closure is stored. In this case, it doesn't make sense to allow  
'function' to be called, because then we wouldn't have anything with which  
to fill the $this pointer.


I guess it could make some sense for static calls, though.

--
Gustavo Lopes

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