Hello Stanislav,

Tuesday, January 13, 2009, 12:07:31 AM, you wrote:

> Hi!

>> 1) a non static closure assigned to an instance changes the closures
>> this to be set to the actual object:

> I'm not sure why would you expect this. If you have closure that has 
> some bound $var inside, and you use it in context which has another 
> $var, you don't expect that $var change to new scope's $var, do you?
> I always thought of closures as taking their variables and context with 
> them, not changing them each time caller changes.

Variables and this are two very different things in PHP and even more so
for closures. Because there this does not reflect the object itself but the
object it is bound to.

> Also, this adds very new thing to PHP - objects that change while being 
> assigned. I am not sure it is a good thing.

Well Closures are a brand new thing in PHP. So far we had nothing even
remotely close to the closures we have right now.

>> 4) Cloning an object assigns the properties correct. Right now we
>> increase the refcount only instead of cloning as that is the default
>> behavior of cloning. Since a normal variable splits on changes nothing
>> ever notices this. For oject types that do not support cloning this is
>> very different though. Now we cannot simply add cloning as then we'd
>> further change closure behavior. And this way we would not fix the this
>> pointer.

> Besides the issue above with changing $this I'm not sure what would 
> proper clone do - i.e. by-val bound variables are by-val anyway, so it 
> shouldn't matter if they are cloned, and by-ref ones should be connected 
> anyway so again it doesn't matter. Am I missing something?
> BTW, why would one clone closures anyway?

I Was not at all speaking of static variables. In fact I suggest we keep
them exactly as they are. Which is probably what you want, based on what
you wrote. And in my opinion it also makes the most sense. A closure keeps
its state.

>> 5) A closure assigned to a property can be called directly rather
>> than just by a temporary variable:
>> $obj->property = function() {}
>> $obj->property();  // valid call

> This will get us into trouble IMHO, as it would not behave too well with 
>   __get/__set and __call. I.e. if we have $foo->nosuchproperty() - 
> should we call __get or __call? So far variables implemented through 
> __get behave exactly like ones implemented through definition - but I 
> don't understand how to reconcile it with this.

Why would you call __get() here? Becasue I did that by mistake in my very
first mail? You clearly have a function call and thus you only go for
__call(). As of today you can already do:

function __call($name, $args) {
  if ($this->properties[$name] instanceof 'Closure') {
    return call_user_func_array($this->property[$name], $args);
  }
}

Now we already have callable properties - directly callable.

> I also don't like having special one-class check inside assignment 
> operators just for this narrow function - it doesn't look like good 
> generic code and I suspect for proper implementation may require 
> instanceof check on each assignment - which would be really bad.

No, becasue Closure cannot be derived as it is a final class. If we change
that later then we simply have to change the check to test for the handler.
We might want to do that anyway as it is faster.

>> 2) The current behavior seems inconsistent as it matters where an
>> assignment of a closure to a proeprty is being performed. OR how a closure
>> is being created.

> Of course it matters how (or, more precisely, where) the closure was 
> created - isn't it the whole point of closure?

It matters how you bind static variables to it as they are taken from the
context. And by the binding you keep the context. Sure all right. But we
bind this in a completely different way.

And when I bind a closure to an object inside that object why should it be
different from an assignment outside the class? And it gets even better, if
you assign that closure to another object it gets private access to the
other classes members; plus you can bind it to the new classes private
members as well. This is a nightmare and plain wrong to me and the part
with accessing another classes private members without knowing will create
a very large WTF factor and conflicts with everythign we ever said about
visibility.

>> 3) If closures get callable by property directly then we end up in a
>> situation where we can have two methods with the same name. That means it
>> is discussable whether we want to allow assignment of a closure to a
>> member variable name that already exists as a private member function.

> This is another thing - does it mean on each assignment we'd have to 
> check if member function with same name doesn't exist? That might break 
> some code in interesting ways too.

I don't see a reason for this. But people might differ. And at the end of
the day the problems arising from this are the least evil.


Best regards,
 Marcus


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

Reply via email to