Hi internals,
As the partial function application RFC has not been accepted, I have
opened voting on https://wiki.php.net/rfc/first_class_callable_syntax. The
vote closes on 2021-07-16.
This RFC uses a syntax that is forward-compatible with partial function
application. Should it not be accepted, I'll explore alternative syntax
possibilities.
Regards,
Nikita
This RFC uses a syntax that is forward-compatible with partial function
application. Should it not be accepted, I'll explore alternative syntax
possibilities.
Given the choice of syntax in this proposal (which I do like)... Is the
following (potentially future) use case precluded by the syntax (whether
or not you like it immediately ;) )?
Basically be able to:
-
be able to refer to an instance method statically (this is currently
an error) -
allow late binding of $this/context/closure scope, either via
bindTo() or via Reflection setClosureThis() (does not exist)class MyController {
public function myAction($name) {
return new Response("Hello, $name");
}
}// Closure with no $this (to be filled in later)
$fn = MyController->myAction(...);$controller = new MyController;
$response = ($fn->bindTo($controller))($params);
-ralph
On Fri, Jul 2, 2021 at 10:32 AM Ralph Schindler
ralph@ralphschindler.com wrote:
This RFC uses a syntax that is forward-compatible with partial function
application. Should it not be accepted, I'll explore alternative syntax
possibilities.Given the choice of syntax in this proposal (which I do like)... Is the
following (potentially future) use case precluded by the syntax (whether
or not you like it immediately ;) )?Basically be able to:
be able to refer to an instance method statically (this is currently
an error)allow late binding of $this/context/closure scope, either via
bindTo() or via Reflection setClosureThis() (does not exist)class MyController {
public function myAction($name) {
return new Response("Hello, $name");
}
}// Closure with no $this (to be filled in later)
$fn = MyController->myAction(...);$controller = new MyController;
$response = ($fn->bindTo($controller))($params);
It would theoretically be:
$fn = MyController::myAction(...);
It currently errors:
Fatal error: Uncaught Error: Non-static method MyController::myAction() cannot be called statically
I would be okay with allowing this, as long as it's bound before it's called.
It would theoretically be:
$fn = MyController::myAction(...);
It currently errors:
Fatal error: Uncaught Error: Non-static method MyController::myAction() cannot be called statically
I would be okay with allowing this, as long as it's bound before it's called.
One other question regarding the current patch. I have not seen this
aspect discussed yet.
From the list in the first proposal section
(https://wiki.php.net/rfc/first_class_callable_syntax#proposal), I am
focusing this question on the few that are by name (strings).. so:
strlen(...);
Foo::method(...);
$classStr::$methodStr(...);
self::{$complex . $expression}(...);
'strlen'(...);
Foo::class, 'method';
Do these have to scan the target function and its signature in order to
wrap them? In the cases of classes above, this will trigger the
autoloader. I wonder if it could create a by-name reference that
resolves the signature at just in time / at call time in these situations?
In context, suppose I am suggesting that something like:
$routes = [
'/my-action' => MyController::myAction(...),
'/other-action => [OtherController::class, 'otherAction'](...),
...
];
would not invoke the autoloader until one of them may be actually
used/called.
This would be similar in philosophy as to how Foo::class creates a fully
qualified string without confirming a class exists at that name when the
scanner and executor sees ::class.
-ralph
On Sat, Jul 3, 2021 at 3:51 PM Ralph Schindler ralph@ralphschindler.com
wrote:
It would theoretically be:
$fn = MyController::myAction(...);
It currently errors:
Fatal error: Uncaught Error: Non-static method MyController::myAction()
cannot be called staticallyI would be okay with allowing this, as long as it's bound before it's
called.One other question regarding the current patch. I have not seen this
aspect discussed yet.From the list in the first proposal section
(https://wiki.php.net/rfc/first_class_callable_syntax#proposal), I am
focusing this question on the few that are by name (strings).. so:strlen(...);
Foo::method(...);
$classStr::$methodStr(...);
self::{$complex . $expression}(...);
'strlen'(...);
Foo::class, 'method';Do these have to scan the target function and its signature in order to
wrap them? In the cases of classes above, this will trigger the
autoloader. I wonder if it could create a by-name reference that
resolves the signature at just in time / at call time in these situations?In context, suppose I am suggesting that something like:
$routes = [ '/my-action' => MyController::myAction(...), '/other-action => [OtherController::class, 'otherAction'](...), ... ];
would not invoke the autoloader until one of them may be actually
used/called.This would be similar in philosophy as to how Foo::class creates a fully
qualified string without confirming a class exists at that name when the
scanner and executor sees ::class.
No, something like this will definitely not be supported as part of this
syntax. It is fundamentally at odds with this proposal, which requires that
callability is validated at point of creation, rather than at point of call
(both of these may differ).
Regards,
Nikita
It would theoretically be:
$fn = MyController::myAction(...);
It currently errors:
Fatal error: Uncaught Error: Non-static method MyController::myAction() cannot be called statically
I would be okay with allowing this, as long as it's bound before it's called.
Could we do this for 8.1? Does something of this scope need an RFC?
I started working up a patch over the weekend, it is 1/2 done (only 7
failing tests).
I would really like to see this behavior come in with the (...) syntax,
as I see it as pretty valuable.
-ralph
On Wed, Jul 7, 2021 at 10:41 PM Ralph Schindler ralph@ralphschindler.com
wrote:
It would theoretically be:
$fn = MyController::myAction(...);
It currently errors:
Fatal error: Uncaught Error: Non-static method MyController::myAction()
cannot be called staticallyI would be okay with allowing this, as long as it's bound before it's
called.Could we do this for 8.1? Does something of this scope need an RFC?
I started working up a patch over the weekend, it is 1/2 done (only 7
failing tests).I would really like to see this behavior come in with the (...) syntax,
as I see it as pretty valuable.
I'm rather strongly opposed to this. MyController::myAction(...) is not
callable, ergo trying to create a callable from it will fail. As I said
before, performing the callability check at time of construction is a core
part of this proposal, that I am not willing to compromise on.
Regards,
Nikita
It would theoretically be:
$fn = MyController::myAction(...);
It currently errors:
Fatal error: Uncaught Error: Non-static method MyController::myAction() cannot be called statically
I would be okay with allowing this, as long as it's bound before it's called.
Could we do this for 8.1? Does something of this scope need an RFC?
I started working up a patch over the weekend, it is 1/2 done (only 7
failing tests).I would really like to see this behavior come in with the (...) syntax,
as I see it as pretty valuable.-ralph
I think this requires an RFC. The behavior of
MyController::myAction(...)
should align with
Closure::fromCallable('MyController::myAction')
, and the latter is
forbidden today. We should use an RFC to support the behavior in both
places. We shouldn't try to sneak it in, especially as Nikita is
opposed.
As the partial function application RFC has not been accepted, I have
opened voting on https://wiki.php.net/rfc/first_class_callable_syntax. The
vote closes on 2021-07-16.This RFC uses a syntax that is forward-compatible with partial function
application. Should it not be accepted, I'll explore alternative syntax
possibilities.
Was replying to a comment on reddit which made me look closer at your
implementation. It looks like this does NOT allow for use of function-like
language constructs.
e.g. $e = echo(...); $p = print(...); $r = require(...); // etc...
1/ Is this intentional?
2/ Is this actually a good thing?
I'm actually of a mind that it's a good thing, as surprising ways to reach
eval() are foot-guns waiting to happen, but wanted to get confirmation.
-Sara
As the partial function application RFC has not been accepted, I have
opened voting on https://wiki.php.net/rfc/first_class_callable_syntax.
The
vote closes on 2021-07-16.This RFC uses a syntax that is forward-compatible with partial function
application. Should it not be accepted, I'll explore alternative syntax
possibilities.Was replying to a comment on reddit which made me look closer at your
implementation. It looks like this does NOT allow for use of function-like
language constructs.
e.g. $e = echo(...); $p = print(...); $r = require(...); // etc...1/ Is this intentional?
Yes.
2/ Is this actually a good thing?
Yes. echo is not a function, so you can't acquire a callable to it.
The actual echo syntax is echo "Foo". PHP allows you to write echo("Foo")
in the same way it allows you to write echo((((("Foo"))))). Don't do it :)
Regards,
Nikita
The actual echo syntax is echo "Foo". PHP allows you to write echo("Foo")
in the same way it allows you to write echo((((("Foo"))))). Don't do it :)
Indeed. Note that this is valid:
echo "hello", " ", "world";
But this is not:
echo("hello", " ", "world");
I have in the past had a bug make it into production because the
parentheses around a call to "include" were mis-placed because of this
incorrect belief that it is "function-like":
if ( include('some_file.php') && bar() )
Is equivalent to this (will always run bar(), then attempt to include
either (string)true or (string)false):
if ( include ('some_file.php' && bar()) )
When what was intended was this:
if ( (include 'some_file.php') && bar() )
Regards,
--
Rowan Tommins
[IMSoP]
Hi internals,
As the partial function application RFC has not been accepted, I have
opened voting on https://wiki.php.net/rfc/first_class_callable_syntax.
The vote closes on 2021-07-16.
The RFC has been accepted unanimously, with 44 votes in favor.
Regards,
Nikita