Andrea Faulds wrote (on 10/08/2014):
On 10 Aug 2014, at 22:00, Rowan Collins <rowan.coll...@gmail.com> wrote:

You're rather pre-supposing the proposed syntax there, and letting it lead the 
semantics rather than vice versa. The point is it would be useful to allow 
creation of a pre-bound closure based on an existing method, so it would be 
good if the syntax allowed that possibility.
Huh? I’m saying it should do the same thing calls do for the sake of consistency. It’d 
be nice if (&$foo->method) could work, but sadly it doesn’t.

I understand that &$foo->method won't work, but that's what I mean by pre-supposing the proposed syntax.

If you had a different syntax, such as £function (I know it's not a sensible choice, but it's an example of something with no conflict), you *would* be able to implement £$foo->method. It would "do the same thing calls do", which is call a non-static method non-statically.

So the question is, is it a) desirable and b) practical to come up with an implementation where that is possible?

Getting a static reference to a non-static method and then binding it feels a 
bit like JS, which has a completely different notion of what a method is.
JavaScript’s methods are bound based on what object they’re used on. PHP’s 
methods are statically bound. That’s not quite the same thing at all.

Yep, that's my point - referencing a method without also referencing the class or object it's bound to is not something that usually happens in PHP, so it feels odd to make it the default behaviour here.

Your proposal requires that to create a reference to a non-static method of the current object, you would do something like this:

$foo = &static::foo;
$foo->bindTo($this);

We could imagine instead having a factory like Closure::wrap(callable $c), where the exact equivalent would be:

$foo = Closure::wrap([static::class, 'foo']);
$foo->bindTo($this);

But you would never write it that way, because we have a way of specifying callables for instance methods, so you'd just write this:

$foo = Closure::wrap([$this, 'foo']);

You might for some reason want to re-bind that to a different object (although I'm not sure why, outside of things you'd expect to use Reflection for anyway), but the default would be referencing its existing binding.


Using the ‘Closure’ class is unfortunate, but I don’t really want to
make unnecessary new Function/Method/etc. classes given they’d all
share the same implementation anyway.
I'm not so sure they'd be identical - a static method or plain function would 
presumably error if you tried to bind it, for instance.
So do static closures, as I’ve already mentioned.

I don’t really see what’s wrong with using our existing class for functions.

In which case what do you think of my second suggestion, of adding methods to allow people to tell whether a closure is bound, bindable, etc? It makes it much easier to write defensive code if you can predict errors rather than catching them.

--
Rowan Collins
[IMSoP]

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

Reply via email to