New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hacklang Method overloading #2532

Closed
alwinmark opened this Issue Apr 24, 2014 · 6 comments

Comments

Projects
None yet
3 participants
@alwinmark
Copy link

alwinmark commented Apr 24, 2014

As Hacklang supports static typing one cool feature would be to enable method overloading.

I would really like to see sth like:

<?hh
class MethodOverloading {

    public function greet(string $adsf): string {
        return "Hello $adsf";
    }

    public function greet(int $int): string {
        return $this->greet("$int");
    }

}

would be awsome!!!

If it is not possible (for example because its to much work as Hack uses the same Parser as PHP), it would be nice if you could explain why.

@jwatzman jwatzman added the hack label Apr 24, 2014

@jwatzman

This comment has been minimized.

Copy link
Member

jwatzman commented Apr 24, 2014

The dynamic nature of PHP makes this a non-starter there IMO -- method resolution would be tricky and require potentially confusing resolution rules, if even possible at all. While we could maybe make it work (with extensive typechecker and runtime changes) if all of your code were in <?hh // strict, it's unclear it would even be worth it -- and forgoing PHP compatibility would almost certainly be not. Moreover, it's not even clear that overloading is a good idea for code readability and error messages -- needing to look for overloads is just more cognitive load when reading code, for what is an unclear but IMO fairly small benefit when writing it.

If you need to emulate overloading, you can do this right now in a type-safe way (danger, code typed directly into github without testing, might have typos but you get the idea):

<?hh // strict
class MethodOverloading {
  public function greet(mixed $arg): string {
    return 'Hello ' . (string)$arg;
  }
}

Or a less trivial example:

<?hh // strict
class MethodOverloading2 {
  public function foo(mixed $arg): string {
    if (is_int($arg)) {
      return 'You passed an int. It squared is ' . (string)($arg*$arg);
    } else if (is_float($arg)) {
      return 'You passed a float. Twice its value is ' . (string)(2.0 * $arg);
    } else {
      return 'You passed something else. It cast to string is ' . (string)$arg;
    }
  }
}

And of course you can just name your methods differently and still call through to one another, similar to your original example (but with, e.g., greetString and greetInt).

@alwinmark

This comment has been minimized.

Copy link

alwinmark commented Apr 25, 2014

Ok Thank you!

Thats one reason I had nearly expected. I also just found out, that Type assertions are made at runtime and not as I was expecting at parsing time.

Nevertheless you guys did a great Job bringing PHP/Hacklang to the next level.

@jwatzman

This comment has been minimized.

Copy link
Member

jwatzman commented Apr 25, 2014

I also just found out, that Type assertions are made at runtime and not as I was expecting at parsing time.

HHVM must check things for all code (Hack or not) as it's running. The typechecker can make checks statically, without running code, but the system for doing it isn't sound unless 100% of your code is in <?hh // strict, so we can't rely on the accuracy of its checks until then. (The runtime's type inference and checking is much much more conservative.)

@jaderfeijo

This comment has been minimized.

Copy link

jaderfeijo commented Oct 21, 2014

Hate to bring more fire to this conversation @jwatzman, but I came across this the other day in the Hack documentation (http://docs.hhvm.com/manual/en/class.hack.mutablevectortv.php) and it appears that the MutableVector interface is overloading some methods from the ConstVector interface. Namely the filter, filterWithKey, keys, map, mapWithKey and zip methods. They appear to be redefined (overloaded) with a new return type to match the MutableVector type. Could you please clarify what exactly is happening in this case?

@jwatzman

This comment has been minimized.

Copy link
Member

jwatzman commented Oct 21, 2014

It's not overriding, it's the same method with a more specific type. To take filter specifically, the version in ConstVector is typed to return a ConstVector<Tv> and the version in MutableVector returns a MutableVector<Tv>. But since MutableVector is a subinterface of ConstVector this is fine, it's actually the same method, the latter version is just being more specific about its return type.

If this is still unclear, consider:

<?hh
interface I1 {
  public function f(): I1;
}
interface I2 extends I1 {
  public function f(): I2;
}
class C implements I2 {
  public function f(): I2 {
    return new C();
  }
}

No conflict, no overloading, no magic -- just a more specific type in I2 than in I1.

@jaderfeijo

This comment has been minimized.

Copy link

jaderfeijo commented Oct 21, 2014

Perfect! It makes sense! I didn't know it was possible to do that! Thanks for the clarification @jwatzman!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment