Hhvm: Typed variadics not supported in PHP code

Created on 31 Mar 2016  路  11Comments  路  Source: facebook/hhvm

<?php

function test(int ...$numbers) {
    echo array_sum($numbers);
}

test(1, 2, 3);
Fatal error: Parameter $numbers is variadic and has a type constraint (int); variadic params with type constraints are not supported in non-Hack files in /tmp/hhtest/test.php on line 3

Currently not supported in PHP as Hack's enforcement is in the typechecker - we have no support for run-time enforcement, which is required to implement this feature for PHP.

mid-pri php5 incompatibility php7 incompatibility

Most helpful comment

To be clear, this is also a PHP 5.6 incompatibility if you change the typehint to array instead. See https://3v4l.org/m5gdA

All 11 comments

@fredemmott Just to emphasize the importance of this issue, I wanted to react to your comments on its parent issue:

we've not came across any real-world examples of people typing variadics in PHP code

I personally maintain a few projects where this is really useful. See for example:

This avoids the burden of having to check the type of each objet manually. I do not want to blindly accept any variable either, as if a bad object is given, I want it to fail early, instead of getting an error in an arbitrary piece of code later, that would be hard to debug.

the runtime verification that PHP requires is very expensive

I just verified that this is not true. I created a quick benchmark that you can use to check by yourself. On my laptop with PHP 7, I get the following results when calling 1000 times a function with 1000 arguments:

$ php variadics-benchmark.php 
Without type-hinting: 0.015783 s
With type-hinting: 0.017840 s
With manual type check: 0.074122 s
Type-hinting overhead: 13.0 %
Type-hinting improvement over manual check: 315.5 %

As you can see, it's still very fast even with a lot of arguments. The type-hinting overhead is just about +13% in CPU time (this drops to barely +1% with a more reasonable number of arguments). This is to be balanced with the cost of _manually_ checking every argument: +315% compared to the type-hinted variadic!

So the performance is a non-issue in PHP 7, the variadics type checks actually greatly improve performance of code that requires a type check anyway.

And for those who want to get the most of every CPU cycle, they can just choose not to use type-hinted variadics. This is not a reason for not implementing it.

As @jurchiks said,

If PHP 7 supports it, you have to support it eventually.

Which is true if I believe @paulbiss on another issue:

Yes, we'd like to be compatible going forward.

I basically agree, except for our definition of 'expensive'; even something most people would consider irrelevant can cost a huge amount of money at our scale. I'd guess support for this would have to be optional (on by default for compatibility), and generate different bytecode. By comparison, the Hack support has _no_ runtime cost.

I especially agree on the importance of compatibility - however, I'm not directly working on HHVM any more, so don't have much time to push for this.

Bump... Any ideas on when will this be fixed. Or any workaround for this?

To be clear, this is also a PHP 5.6 incompatibility if you change the typehint to array instead. See https://3v4l.org/m5gdA

Just like @stof I'm also seeing this with php 5 mode on 3.15.2 with type constraint (array)

Fatal error: Parameter $argv is variadic and has a type constraint (array);
variadic params with type constraints are not supported in non-Hack files in
/doctrine/dbal/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php(345)(c26a62d6b8349ddbaa7782b3f4afa3ef) : eval()'d code on line 255

@fredemmott @aorenste Please add the php5 incompatibility label

@aorenste thanks for adding the php5 incompatibility label, I look forward to this issue being resolved.

Another issue on php 5 mode on 3.15.3 with type constraint (callable)

Fatal error: Parameter $callbacks is variadic and has a type constraint (callable);
variadic params with type constraints are not supported in non-Hack files in
/lstrojny/functional-php/src/Functional/Partition.php on line 41

I ran into the same problem. This makes phpunit-6.5.2 and HHVM incompatible, as far as I can see.

As @cgogolin said, lack of support for ...$variadic makes PhpUnit 6.4+ tests fail and thus fail all hhvm builds. Is there any way to make it work, except from rewriting all tests to another framework?

Error:

Fatal error: Uncaught Error: Parameter $constraints is variadic and has a type constraint (Constraint); variadic params with type constraints are not supported in non-Hack files in phar://phpunit-6.5.2.phar/phpunit/Framework/Constraint/LogicalAnd.php:29
Stack trace:
#0 /home/travis/.phpenv/versions/hhvm-stable/bin/phpunit(103): include()
#1 {main}

I am going over old issues on this repository, to see which ones apply to the current versions of hhvm.

This issue applies to running php code on hhvm. Hhvm nolonger supports running php code since hhvm version 4.0.0.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

turadg picture turadg  路  6Comments

Sakretsos picture Sakretsos  路  7Comments

ahmadazimi picture ahmadazimi  路  6Comments

HRMsimon picture HRMsimon  路  4Comments

caioiglesias picture caioiglesias  路  6Comments