KEMBAR78
Fully support generics, improve alignment with PHP · Issue #5317 · facebook/hhvm · GitHub
Skip to content

Fully support generics, improve alignment with PHP #5317

@mindplay-dk

Description

@mindplay-dk

After some days of testing, our team consistently found that the generic type system seems to basic and not very useful.

To give a couple of quick examples of things we tried that, to our suprise, didn't work:

<?hh

class Repository<T> {
  // ...
}

class User {
  // ...
}

$user_repo = new Repository<User>(); // nope :-(

And:

<?hh

class Hook<T> {
  // ...
}

function hook<T>() : Hook<T> {
  return new Hook<T>(); // nope :-(
}

$some_hook = hook<LoginEvent>(); // nope :-(

It seems that generics work only in declarations (extends, implements, etc.) but never in expressions? That's not very useful and prevents many common and useful patterns with generics.

It appears to be this way because generics are only type-hints and don't really seem to have a run-time footprint? To explain this better, here's an example of something class-related in PHP:

<?php

class Foo {
    public static function hello() {
        var_dump(get_called_class());
    }
}

class Bar extends Foo {
}

Foo::hello(); // => "Foo"

Bar::hello(); // => "Bar"

Point being, type-names generated at call-time actually "exist" and can be obtained at run-time. The same is true for most type-related things in PHP - reflection will let you discover lots of type-related information at run-time.

In contrast, generic type arguments in Hack don't seem to "exist" at run-time - they are static type-hints only? This doesn't seem true to PHP as such - for example, it would seem natural to expect something like the following to work:

class Foo<T> {}

class Bar {}

$foo = new Foo<Bar>();

$class = new ReflectionClass($foo);

echo $class->getTypeArgument(0)->getClass()->getName(); // => "Bar"

We encountered other surprising behaviors, but I'm not going to get into them all - bottom, there were too many surprises and shortcomings for developers who are familiar with generics in other languages like C# and TypeScript.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions