# PHP 8: Method Overloading, The Ressurection

- Thread: https://externals.io/message/104073
- Original archive: https://news-web.php.net/php.internals/104073
- Started by David Rodrigues on 2019-02-03T18:39:03+00:00
- Messages: 7
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #104073 — David Rodrigues — 2019-02-03T18:39:03+00:00

URL: https://externals.io/message/104073#104073

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

---

## #104078 — Christoph M. Becker — 2019-02-03T19:00:22+00:00

URL: https://externals.io/message/104073#104078 · In reply to: #104073

> 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

---

## #104080 — Rowan Collins — 2019-02-03T19:19:33+00:00

URL: https://externals.io/message/104073#104080 · In reply to: #104078

> 
>
> > […]
> 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]

---

## #104081 — David Rodrigues — 2019-02-03T19:51:32+00:00

URL: https://externals.io/message/104073#104081 · In reply to: #104080

Em dom, 3 de fev de 2019 às 17:19, Rowan Collins <rowan.collins@gmail.com>
escreveu:

> 
> > […]
>
>
> 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

---

## #104084 — Marcos Passos — 2019-02-03T21:18:26+00:00

URL: https://externals.io/message/104073#104084 · In reply to: #104081

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:
>
> > […]
>
> This example could be complex. So, what other languages does in cases like
> that? Java, for instance.
>
>
> > […]
> signature.
> > […]
>
> 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.
>
>
> > […]
>
> --
> David Rodrigues

---

## #104085 — Cees-Jan Kiewiet — 2019-02-03T21:21:40+00:00

URL: https://externals.io/message/104073#104085 · In reply to: #104078

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:

> 
>
> > […]
>
> 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

---

## #104087 — Dan Ackroyd — 2019-02-03T23:16:35+00:00

URL: https://externals.io/message/104073#104087 · In reply to: #104073

>
> 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;
>
> > […]

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);
