Hello everybody!
I know that method overloading was discussed on past and because a lot of
reasons it was declined [1]. I think that it should be considered maybe for
PHP 8, but for now I would like to suggest a different implementation.
Because of a stronger support to parameter types that PHP has now, I think
that is possible make this process more faster than before by handling it
only in case of exceptions. I wil explain better.
The biggest problem that I see about this topic is the loss of performance,
but I think that it could be avoided by create a new keyword "overload"
that should be applied before methods that could be overloaded. For
instance:
overload function sum(int $a, int $b): int;
overload function sum(float $b, float $b): float;
In this case, when call a method PHP could identify if it have a overloaded
implementation, so ONLY in this case it will reduce performace to decided
which implementation it should call.
I don't know how PHP could treats it internally, but when overload keyword
is identified, I think that it could generates a hash like
"sum/int,int/int" and "sum/float,float/float" (method name, parameters
types, return type). I don't know. So when method is called, it should
convert the argument types and create a similar hash, making possible to
identify what overloaded method should be run. It seems slow, but I think
that the opcache could simplify the next operations to connect directly the
call to the correct overloaded method.
Please, tell what do you think, because I really wants method overload on
PHP 8 or before. Currently we should do some code hacks to make it possible
that certainly is slower than a native implementation.
Thanks!
[1] https://marc.info/?l=php-internals&m=121397217528280&w=2
--
David Rodrigues
overload function sum(int $a, int $b): int;
overload function sum(float $b, float $b): float;
Which function would sum(17.4, 42) call? Also consider:
sum(PHP_INT_MAX, PHP_INT_MAX)
vs.
sum(PHP_INT_MAX+1, PHP_INT_MAX+1)
--
Christoph M. Becker
overload function sum(int $a, int $b): int;
overload function sum(float $b, float $b): float;
Which function would sum(17.4, 42) call? Also consider:sum(PHP_INT_MAX, PHP_INT_MAX)
vs.
sum(PHP_INT_MAX+1, PHP_INT_MAX+1)
Yes, marking overloaded functions explicitly definitely helps, but I
think the dispatch part is more complex than it first seems. Classes and
interfaces require a bit of subtlety too:
class Foo {}
class Bar extends Foo {}
overload function foo(Foo $a, Foo $b);
overload function foo(Foo $a, Bar $b);
overload function foo(Bar $a, Foo $b);
foo(new Bar, new Bar);
There are plenty of cases more complex than this, e.g. when a class
implements multiple interfaces, and you need to find a matching signature.
That's not to say it's impossible, just don't underestimate the edge
cases you'll need to legislate for.
Oh, and note that return types can't participate in overloading, because
there's no concept of "desired type" to choose between them.
Regards,
--
Rowan Collins
[IMSoP]
Em dom, 3 de fev de 2019 às 17:19, Rowan Collins rowan.collins@gmail.com
escreveu:
overload function sum(int $a, int $b): int;
overload function sum(float $b, float $b): float;
Which function would sum(17.4, 42) call? Also consider:sum(PHP_INT_MAX, PHP_INT_MAX)
vs.
sum(PHP_INT_MAX+1, PHP_INT_MAX+1)
Yes, marking overloaded functions explicitly definitely helps, but I
think the dispatch part is more complex than it first seems. Classes and
interfaces require a bit of subtlety too:class Foo {}
class Bar extends Foo {}overload function foo(Foo $a, Foo $b);
overload function foo(Foo $a, Bar $b);
overload function foo(Bar $a, Foo $b);foo(new Bar, new Bar);
This example could be complex. So, what other languages does in cases like
that? Java, for instance.
There are plenty of cases more complex than this, e.g. when a class
implements multiple interfaces, and you need to find a matching signature.That's not to say it's impossible, just don't underestimate the edge
cases you'll need to legislate for.Oh, and note that return types can't participate in overloading, because
there's no concept of "desired type" to choose between them.
You are right, in general. But still is possible identify the desired type
if return is used as argument to a typed parameter, but I still thinks that
it could not be done in general terms, so maybe we should not includes
return type to overloading.
Regards,
--
Rowan Collins
[IMSoP]--
--
David Rodrigues
I believe we can adopt the behaviour of mature languages that supports this
feature. Java, for instance, throw a compile-time error saying that the
method signature is ambiguous.
Em dom, 3 de fev de 2019 às 17:19, Rowan Collins rowan.collins@gmail.com
escreveu:overload function sum(int $a, int $b): int;
overload function sum(float $b, float $b): float;
Which function would sum(17.4, 42) call? Also consider:sum(PHP_INT_MAX, PHP_INT_MAX)
vs.
sum(PHP_INT_MAX+1, PHP_INT_MAX+1)
Yes, marking overloaded functions explicitly definitely helps, but I
think the dispatch part is more complex than it first seems. Classes and
interfaces require a bit of subtlety too:class Foo {}
class Bar extends Foo {}overload function foo(Foo $a, Foo $b);
overload function foo(Foo $a, Bar $b);
overload function foo(Bar $a, Foo $b);foo(new Bar, new Bar);
This example could be complex. So, what other languages does in cases like
that? Java, for instance.There are plenty of cases more complex than this, e.g. when a class
implements multiple interfaces, and you need to find a matching
signature.That's not to say it's impossible, just don't underestimate the edge
cases you'll need to legislate for.Oh, and note that return types can't participate in overloading, because
there's no concept of "desired type" to choose between them.You are right, in general. But still is possible identify the desired type
if return is used as argument to a typed parameter, but I still thinks that
it could not be done in general terms, so maybe we should not includes
return type to overloading.Regards,
--
Rowan Collins
[IMSoP]--
--
David Rodrigues
Well there should be a:
overload function sum(float $b, float $b): float;
in that case or throw an error for no matching function available imho.
On Sun, Feb 3, 2019 at 8:00 PM Christoph M. Becker cmbecker69@gmx.de
wrote:
overload function sum(int $a, int $b): int;
overload function sum(float $b, float $b): float;Which function would sum(17.4, 42) call? Also consider:
sum(PHP_INT_MAX, PHP_INT_MAX)
vs.
sum(PHP_INT_MAX+1, PHP_INT_MAX+1)
--
Christoph M. Becker--
--
http://wyrihaximus.net/
Website
http://wyrihaximus.net/?utm_source=signature&utm_medium=email&utm_campaign=emailsignature
| Blog
http://blog.wyrihaximus.net/?utm_source=signature&utm_medium=email&utm_campaign=emailsignature
|
Github https://github.com/WyriHaximus | Linkedin
http://nl.linkedin.com/in/ceesjankiewiet | Twitter
http://twitter.com/wyrihaximus | Facebook
<http://www.facebook.com/CeesJan.Kiewiet
Hello everybody!
The biggest problem that I see about this topic is the loss of performance,
Although performance impact might be a problem, my impression is that
PHP has some problems supporting method overloading that don't exist
in other languages.
So, what other languages does in cases like
that? Java, for instance.
Java doesn't have type-juggling so they avoid quite a few problems
with dynamic types.
Marcos Passos wrote:
Java, for instance, throw a compile-time error saying that the
method signature is ambiguous.
Java compiles all the code in a program before running it, which makes
that solution possible. PHP doesn't and so has to make some decisions
at run-time.
As Christoph wrote:
overload function sum(int $a, int $b): int;
overload function sum(float $b, float $b): float;Which function would sum(17.4, 42) call?
That's the fundamental problem that would need addressing.
I believe that to have a chance of passing, any method overloading RFC
would need to have a really comprehensive answer that covers all of
the edge cases.
But in addition to that, a really strong argument for why method
overloading is a good thing needs to be made as well, particularly as
the equivalent behaviour can be done in userland*.
btw It is possible, that the thing mostly likely to happen, and
provide the most benefit for you, would be support in your IDE for
autocompletion as implemented in userland. Which might take a lot less
effort than implmenting the feature in PHP core...
cheers
Dan
Ack
- userland implementation:
/**
-
@method sum(int $a, int $b): int;
-
@method sum(float $b, float $b): float;
*/
class Foo
{
public function __call($name, $arguments)
{
if ($name === 'sum' && is_int($arguments[0]) && is_int($arguments[1])) {
return $this->sumInts($arguments[0], $arguments[1]);
}
if ($name === 'sum' && is_float($arguments[0]) &&
is_float($arguments[1])) {
return $this->sumFloats($arguments[0], $arguments[1]);
}
throw new \InvalidArgumentException("Don't know how to call this");
}private function sumInts(int $a, int $b): int
{
// echo "sumInts was called.\n";
return $a + $b;
}private function sumFloats(int $a, int $b): int
{
// echo "sumFloats was called.\n";
return $a + $b;
}
}
$foo = new Foo();
$foo->sum(4, 4);
$foo->sum(4.1, 4.1);