3

I was trying to figure out how to implement a Visitor pattern in Hack. It obviously requires function-overloading polymorhism, but as I have tested, this examle:

<?hh // strict
class Visitor {
    public function visit(string $s) : void {}
    public function visit(int $i) : void {}
}

produces the usual PHP's

Fatal error: Redeclared method Visitor::visit in hh-polymorphism.php on line 4

And since this failed, then I would like to ask if there are plans to support this in future? Or are there any factors that would prevent this from being implemented?

Maciej Sz
  • 11,151
  • 7
  • 40
  • 56
  • 1
    You can just name your functions `visitString`, `visitInt` etc.. The visitor pattern does not need overloading, it's just usually done that way. – sepp2k Aug 03 '14 at 16:09
  • @sepp2k: yes, but that is not the point here. I also heard somewhere that anything above assembler is just a syntactic sugar. – Maciej Sz Aug 04 '14 at 09:29

1 Answers1

3

We almost certainly will not be able to have overloading in Hack, as I explained in this feature request. You can see there for a detailed answer, but the crux of the issue is that it would totally break interoperability with vanilla PHP, or even partial mode -- you need full type information in order to actually resolve the overload, which we can't promise we have except in 100% strict mode. (There are other reasons too, see that link.)

For your example, you can always do something like this, taking advantage of mixed and Hack's flow sensitivity:

<?hh // strict
class Visitor {
  public function visitString(string $s): void {
    // ...
  }
  public function visitInt(int $i): void {
    // ...
  }
  public function visit(mixed $m): void {
    if (is_int($m)) {
      $this->visitInt($m);
    } else if (is_string($m)) {
      $this->visitString($m);
    } else if (...) {
      ...
    } else {
       invariant_violation('Unexpected type in visitor: %s', gettype($m));
    }
  }
}
Josh Watzman
  • 7,060
  • 1
  • 18
  • 26
  • Ok, I get how method resolution can be tricky, especially at runtime. But I fail to see how this would break interoperability. Can you explain in more detail what you mean by that? As I understand the type checker is already in place in `hhvm` and it is operating at runtime. One more step (ie. `tryResolvePolyMethod`) just before raising type error would not break anything. – Maciej Sz Aug 03 '14 at 20:35
  • The typechecker is *not* inside `hhvm` and does not fully operate at runtime. Most of the Hack type system is enforced by the `hh_client`/`hh_server` static analysis tool, not by the runtime itself. When actually executing code, `hhvm` has erasure semantics for generics, among other things -- so no, we don't necessarily have the full, rich type information that `hh_client` has. – Josh Watzman Aug 04 '14 at 04:44
  • But you have the information required to raise `Fatal error: Argument 1 passed to Foo::doFoo() must be an instance of string, int given`. Would this not be sufficient for the overloading to work? Sorry for being inquisitive, I'm just trying to understand whether this is an actual interoperability issue or just a platform limitation. – Maciej Sz Aug 04 '14 at 09:26
  • 1
    Yes, but then overload resolution is based on runtime types instead of static type information. This can cause surprising behavior coming from Java or C++, which AIUI base it on static type information when derived classes and polymorphism come into play. Not to mention the interoperability with untyped code (anything we add needs to work with untyped code even if it's targeted with strict mode in mind). Basically a call to `$this->foo($bar)` varies depending on what `$bar` is. So mostly interop issue. (There's also a platform limitation on actually getting the static information into HHVM.) – Josh Watzman Aug 04 '14 at 19:10
  • This answer might need to be changed soon, because the HHVM team announced that they won't support PHP in the future. – Crouching Kitten Sep 13 '18 at 13:24
  • 1
    Dropping vanilla PHP support yes, but not dropping support for partially-typed code (at least not yet). The same problem occurs there. I'll poke the team about this the next time I run into them (I no longer work on HHVM/Hack myself) but I'd be surprised if this were planned any time soon. – Josh Watzman Nov 18 '18 at 23:42