Hi,
My idea is somehow related to this one: Syntax for variadic
functionshttps://wiki.php.net/rfc/variadics
It is not a competitive idea but a supplemental one.
So, the main point is to write different implementations for the functions
with the same name, but with different of arguments count or/and type:
class Config { /** * Returns property value * @param string $key *
@returnmixed /
public function prop($key) { return isset($this->prop[$key]) ? $this->prop[
$key] : null; } /* * Sets property value * @param string $key *
@parammixed $value *@returnConfig */
public function prop($key, $value) { $this->prop[$key] = $value; return
$this; } }
Also it will be possible to change arguments during inheritance:
class Figure { /** * Calculate perimeter of an arbitrary figure *
@paramarray $angles @returnint /
public function calcPerimeter(array $angles) { return array_sum($angles); }
} class Square extends Figure { / * Calculate perimeter of a square
*@paramint $angle @returnint /
public function calcPerimeter($angle) { return 4 * $angle; } } class
Rectangle extends Figure { / * Calculate perimeter of a rectangle *
@paramint $height *@paramint $width *@returnint */
public function calcPerimeter($height, $width) { return 2 * ($height +
$width); } }
The advantages of the syntax are:
- It's immediately clear what function implements.
- The function becomes cleaner, without a lot of if-else constructions.
- A great opportunity to change function arguments during inheritance.
Regards,
Oleg Poludnenko
Hello there.
You can actually do the first part using __call($methodName, array $args). It's a little more complex to do that, but consider that as a current solution. Alternatively, use func_get_args()
inside your function, or set the second parameter like method($arg1, $arg2=null) and check if it is, or isn't null using if(is_null($arg2)), and then do what the function should return on either scenario. I know, you are listing these cases within your list of benefits, but one if is less work than having PHP decide which "version" of the function you're wanting to use - I bet it'd make the actual runtime slightly slower.
The second part sounds interesting IMHO, but I somehow doubt it'd be accepted. But we'll see.
Kind regards, Ingwie
Am 05.11.2013 um 14:03 schrieb Oleg Poludnenko oleg@poludnenko.info:
Hi,
My idea is somehow related to this one: Syntax for variadic
functionshttps://wiki.php.net/rfc/variadics
It is not a competitive idea but a supplemental one.So, the main point is to write different implementations for the functions
with the same name, but with different of arguments count or/and type:class Config { /** * Returns property value * @param string $key *
@returnmixed /
public function prop($key) { return isset($this->prop[$key]) ? $this->prop[
$key] : null; } /* * Sets property value * @param string $key *
@parammixed $value *@returnConfig */
public function prop($key, $value) { $this->prop[$key] = $value; return
$this; } }Also it will be possible to change arguments during inheritance:
class Figure { /** * Calculate perimeter of an arbitrary figure *
@paramarray $angles @returnint /
public function calcPerimeter(array $angles) { return array_sum($angles); }
} class Square extends Figure { / * Calculate perimeter of a square
*@paramint $angle @returnint /
public function calcPerimeter($angle) { return 4 * $angle; } } class
Rectangle extends Figure { / * Calculate perimeter of a rectangle *
@paramint $height *@paramint $width *@returnint */
public function calcPerimeter($height, $width) { return 2 * ($height +
$width); } }The advantages of the syntax are:
- It's immediately clear what function implements.
- The function becomes cleaner, without a lot of if-else constructions.
- A great opportunity to change function arguments during inheritance.
Regards,
Oleg Poludnenko
On Tue, Nov 5, 2013 at 2:03 PM, Oleg Poludnenko oleg@poludnenko.infowrote:
Hi,
My idea is somehow related to this one: Syntax for variadic
functionshttps://wiki.php.net/rfc/variadics
It is not a competitive idea but a supplemental one.So, the main point is to write different implementations for the functions
with the same name, but with different of arguments count or/and type:class Config { /** * Returns property value * @param string $key *
@returnmixed /
public function prop($key) { return isset($this->prop[$key]) ? $this->prop[
$key] : null; } /* * Sets property value * @param string $key *
@parammixed $value *@returnConfig */
public function prop($key, $value) { $this->prop[$key] = $value; return
$this; } }Also it will be possible to change arguments during inheritance:
class Figure { /** * Calculate perimeter of an arbitrary figure *
@paramarray $angles @returnint /
public function calcPerimeter(array $angles) { return array_sum($angles); }
} class Square extends Figure { / * Calculate perimeter of a square
*@paramint $angle @returnint /
public function calcPerimeter($angle) { return 4 * $angle; } } class
Rectangle extends Figure { / * Calculate perimeter of a rectangle *
@paramint $height *@paramint $width *@returnint */
public function calcPerimeter($height, $width) { return 2 * ($height +
$width); } }The advantages of the syntax are:
- It's immediately clear what function implements.
- The function becomes cleaner, without a lot of if-else constructions.
- A great opportunity to change function arguments during inheritance.
Regards,
Oleg Poludnenko
Would you mind putting your code in a gist/pastebin (or re-sending the mail
with proper formatting)? It's hard to understand what this is about when
the code is all in one line :)
Nikita
I had nothing to do, so here we go: https://gist.github.com/IngwiePhoenix/e7fbee9f769fc137250d
Am 05.11.2013 um 19:09 schrieb Nikita Popov nikita.ppv@gmail.com:
On Tue, Nov 5, 2013 at 2:03 PM, Oleg Poludnenko oleg@poludnenko.infowrote:
Hi,
My idea is somehow related to this one: Syntax for variadic
functionshttps://wiki.php.net/rfc/variadics
It is not a competitive idea but a supplemental one.So, the main point is to write different implementations for the functions
with the same name, but with different of arguments count or/and type:class Config { /** * Returns property value * @param string $key *
@returnmixed /
public function prop($key) { return isset($this->prop[$key]) ? $this->prop[
$key] : null; } /* * Sets property value * @param string $key *
@parammixed $value *@returnConfig */
public function prop($key, $value) { $this->prop[$key] = $value; return
$this; } }Also it will be possible to change arguments during inheritance:
class Figure { /** * Calculate perimeter of an arbitrary figure *
@paramarray $angles @returnint /
public function calcPerimeter(array $angles) { return array_sum($angles); }
} class Square extends Figure { / * Calculate perimeter of a square
*@paramint $angle @returnint /
public function calcPerimeter($angle) { return 4 * $angle; } } class
Rectangle extends Figure { / * Calculate perimeter of a rectangle *
@paramint $height *@paramint $width *@returnint */
public function calcPerimeter($height, $width) { return 2 * ($height +
$width); } }The advantages of the syntax are:
- It's immediately clear what function implements.
- The function becomes cleaner, without a lot of if-else constructions.
- A great opportunity to change function arguments during inheritance.
Regards,
Oleg PoludnenkoWould you mind putting your code in a gist/pastebin (or re-sending the mail
with proper formatting)? It's hard to understand what this is about when
the code is all in one line :)Nikita
I had nothing to do,
With such statements be careful: A mail here goes to a thousand or so
readers, saving them time is notable and helps to get responses.
so here we go: https://gist.github.com/IngwiePhoenix/e7fbee9f769fc137250d
There are two things which have to be solved for this being possible:
* There needs to be a backwards compatible way to handle the fact
that PHP functions accept variable amounts of parameters
currently
* This has to be implemented in a way not slowing down all
function calls
For the first item think about code like this:
class B {
function foo() { func_get_ars(); }
}
class E extends B {
function foo($bar = null) { func_get_ars(); }
}
$o = new E;
$o->foo(1, 2);
With the logic from the idea B::foo() and E::foo() are different
methods, with current PHP they are overriding each other. Currently this
call E::foo(). what should happen After your change? Break lots of code?
For the second item: Function calls in PHP are relatively slow already
and we have no good way to "bind" the calls during compilation so we
always have to resolve the call at run time. Consider this:
function foo(someInterface $o) {
$o->method();
}
There we don't know which method to call. Unless there is a good idea
and a patch I expect this to slow down each and every function call.
which in my perspective is a no-go. Languages like C++ "mangle" the
parameters in the function name, which is complicated ina dynamic
language lie PHP, and have more information (when compiling that sample
function above PHP doesn't need the definition of someInterface, yet, it
might not exist, yet) Maybe somebody has an idea for a good
implementation. But till then I'd put this aside.
johannes
Johannes, thank you for your complete response. I've made a complex
brainstorm with my colleagues and with a local community (
http://habrahabr.ru/post/198980/). So it took a long time. Nevertheless
I've gotten an answers to your questions. And here they are. We need to
implement two new modifiers: override and dynamic. The first one should
be used to designate a function which overrides it's parent: override
public function calcPerimeter() { ... } We are allowed to override only
methods defined as abstract (without implementation) or dynamic (contains
implementation). So the new modifier dynamic designates that function
could be overridden and it has implementation.
Here there is a code sample: https://gist.github.com/uaoleg/7596995
On Tue, Nov 5, 2013 at 10:21 PM, Johannes Schlüter
johannes@schlueters.dewrote:
I had nothing to do,
With such statements be careful: A mail here goes to a thousand or so
readers, saving them time is notable and helps to get responses.so here we go:
https://gist.github.com/IngwiePhoenix/e7fbee9f769fc137250dThere are two things which have to be solved for this being possible:
* There needs to be a backwards compatible way to handle the fact that PHP functions accept variable amounts of parameters currently * This has to be implemented in a way not slowing down all function calls
For the first item think about code like this:
class B {
function foo() { func_get_ars(); }
}
class E extends B {
function foo($bar = null) { func_get_ars(); }
}
$o = new E;
$o->foo(1, 2);With the logic from the idea B::foo() and E::foo() are different
methods, with current PHP they are overriding each other. Currently this
call E::foo(). what should happen After your change? Break lots of code?For the second item: Function calls in PHP are relatively slow already
and we have no good way to "bind" the calls during compilation so we
always have to resolve the call at run time. Consider this:function foo(someInterface $o) {
$o->method();
}There we don't know which method to call. Unless there is a good idea
and a patch I expect this to slow down each and every function call.
which in my perspective is a no-go. Languages like C++ "mangle" the
parameters in the function name, which is complicated ina dynamic
language lie PHP, and have more information (when compiling that sample
function above PHP doesn't need the definition of someInterface, yet, it
might not exist, yet) Maybe somebody has an idea for a good
implementation. But till then I'd put this aside.johannes
Here there is a code sample: https://gist.github.com/uaoleg/7596995
That sample fails the Liskov substitution principle. Any instance of
figure has to have a calcPerimeter method taking zero arguments else you
can't use them interchangeably what the base class should guarantee.
http://en.wikipedia.org/wiki/Liskov_substitution_principle
johannes