Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:76333 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 62214 invoked from network); 4 Aug 2014 12:11:36 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 4 Aug 2014 12:11:36 -0000 Authentication-Results: pb1.pair.com smtp.mail=ajf@ajf.me; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ajf@ajf.me; sender-id=pass Received-SPF: pass (pb1.pair.com: domain ajf.me designates 192.64.116.200 as permitted sender) X-PHP-List-Original-Sender: ajf@ajf.me X-Host-Fingerprint: 192.64.116.200 imap1-2.ox.privateemail.com Received: from [192.64.116.200] ([192.64.116.200:43898] helo=imap1-2.ox.privateemail.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 64/72-46246-7787FD35 for ; Mon, 04 Aug 2014 08:11:35 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.privateemail.com (Postfix) with ESMTP id EE297B00085; Mon, 4 Aug 2014 08:11:57 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at imap1.ox.privateemail.com Received: from mail.privateemail.com ([127.0.0.1]) by localhost (imap1.ox.privateemail.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id FKdaas7EH51Y; Mon, 4 Aug 2014 08:11:57 -0400 (EDT) Received: from [192.168.0.15] (unknown [90.210.122.167]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.privateemail.com (Postfix) with ESMTPSA id 83EEEB0007B; Mon, 4 Aug 2014 08:11:54 -0400 (EDT) Content-Type: text/plain; charset=windows-1252 Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\)) In-Reply-To: <53DF2BED.10103@sugarcrm.com> Date: Mon, 4 Aug 2014 13:11:51 +0100 Cc: PHP internals Content-Transfer-Encoding: quoted-printable Message-ID: <06F3EF08-21B1-49AD-9D9D-5043C69AC1D8@ajf.me> References: <53DF2BED.10103@sugarcrm.com> To: Stas Malyshev , Marco Pivetta , Nikita Nefedov X-Mailer: Apple Mail (2.1878.6) Subject: Re: [PHP-DEV] [RFC] Closure::call and Function Referencing as Closures From: ajf@ajf.me (Andrea Faulds) Good morning! On 4 Aug 2014, at 06:48, Nikita Nefedov wrote: > Hey Andrea, >=20 > I really love function referencing RFC, this is something I miss in = PHP and would I have a voting right I'd would +1 even in this state of = it. > But I dislike a bit the fact that we start to use Closure for = everything, I really wish we had a dedicated type for functions (read = functions as a first-class citizens). I was originally going to go to the effort of adding a function = reference class, but then I realised it=92d be simpler and make more = sense to just use Closure. To be honest I don=92t think it matters much. If it really bothers = enough people, we could change the class=92s name to Function or = something and make Closure an alias, but I don=92t see the point. On 4 Aug 2014, at 07:45, Stas Malyshev wrote: > This syntax collides with by-ref assignment and by-ref arrays, which = is > not good. Different things should not look the same. It doesn=92t collide, there is no syntactical ambiguity at an engine = level, at least. It does unfortunately look similar, however. The choice = of syntax is largely for a lack of better alternatives. It also matches = what C and C++ do. I had wanted to do something like =91function = foobar=92, but that=92s clunky and actually couldn=92t be done in the = parser. I wondered what Hack does here (since it needs such a syntax to = avoid breaking the type checker), but they have a horrible fun(=91foobar=92= ) pseudo-function. Someone, I think it was Anthony, pointed out to me = that & wasn=92t actually syntactically ambiguous like I=92d thought, so = I decided to go with that. Since you can=92t reference constants, and = since this doesn=92t support dynamic references, I think it will not be = that confusing.=20 > I'm not sure also how exactly non-closures can function as closures - = if > you take SplFixedArray::getSize and rebind it to SplFileObject, what = is > supposed to happen? A fatal error, as methods of internal classes can=92t be bound to other = classes. This is our current behaviour anyway if you try to do that. > I also do not understand why one needs &strlen if "strlen" works just > fine. The hope is that it=92d be more obvious a function is being referenced = without needing to know the signature of the function to which the = callable is being passed. I suppose it also means you could type hint = for Closure instead of callable to guarantee you get an object you can = use the Closure methods on. > Only to declare "PHP now has first-class functions"? You can > declare it right now. No need to change the syntax for that, since the > engine does exactly the same and no additional capabilities appear > (though additional problems - e.g. rebinding non-closures - do). PHP=92s functions aren=92t first-class, we just have a way to reference = them with strings. What we do is similar to what C does with function = pointers. An advantage of being able to get normal functions and methods = as closures is it means that anything we add to the Closure class can be = used on them. For example, if we added built-in partial application = (something I=92d sure like to see, it=92s just difficult to implement), = you=92d be able to use it on any existing userland or extension = function. If we added built-in currying, a related feature, you=92d also = be able to use it. The syntax means PHP no longer has two classes of = functions, essentially. On 4 Aug 2014, at 12:36, Marco Pivetta wrote: > Is the advantage of `Closure#call()` only performance? Because I don't = see other advantages otherwise, and I don't think the performance impact = is relevant. There is a performance advantage which I=92m going to test at some = point, but that=92s not why I propose adding it. It is to simplify = binding closures. It=92s not an uncommon operation to want to bind at = call-time in other languages, and it can be useful. > As for the function referencing RFC, I like it, but it is an annoying = syntax that seems to have been built just to accomodate the parser, and = that can be worked around in userland with overhead and more typing: >=20 > $functionReference =3D function ($param) { return = functionName($param); }; That doesn=92t work properly for class methods, both instance and = static. It doesn=92t even work properly for normal functions, as you=92re = stripping away parameter information. > A syntax that I'd like, and which is IMO BC compatible would = be`::function`: >=20 > array_map(count::function, [[1, 2], [3, 4]]); >=20 > This is also very similar and similarly readable to what we have right = now with PHP 5.5 through the `::class` meta-constant. > There's also no way to use `function` as a constant anywhere, so it = should be safe to use that right now. That syntax isn=92t doable in the parser and isn't backwards-compatible = anyway. Classes and functions share the same namespace, so what do you = do when I have a class called FooBar and a function called FooBar? How = about if I have a class with a constant named function? How do you = propose to implement this pseudo-class system where functions act like = classes in only one case, when fetching this fake class constant? How do = you deal with the fact that constants cannot (with very good reason) be = objects? The idea is good, it just falls down from a practical = standpoint. Thanks. -- Andrea Faulds http://ajf.me/