-
Notifications
You must be signed in to change notification settings - Fork 7.7k
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
Added mixed argument type & return type #2603
Conversation
@sgolemon @remicollet Hi, do you think this would still be acceptable for 7.2? |
5c0b355
to
e1142bb
Compare
I was recently hit by this oddity, I actually thought we reserved it and made it possible with the introduction in 7.0, get this in! |
|
Ping @sgolemon @remicollet - what do you think about this, is it already too late or would it be acceptable as a self-contained addition aliasing current behavior? |
You have missed the official feature freeze (yesterday), while the branch is in pre-release mode, we can't do anything. The thing to do is let the RFC process run, we can see where we are at the end of that once all discussion and voting is done. It may be acceptable to merge once GA, although this is not my call. You have permission to write an rfc on wiki. |
@krakjoe Thanks. 👍 |
@Majkl578 have you started RFC discussion? |
Not yet, it's not finished and there is plenty of time for 7.3. :) |
I must admit I have no clue why one build target fails on two of these tests and the other one is green, both Travis and AppVeyor. It was fine before rebase in which I only changed type code in zend_types.h. :/ |
Why would you typehint a non type? Then just don't typehint -.-, this undoes everything typehinting was supposed to fix. |
@jordyvandomselaar @carusogabriel answer for your question is in first comment — this feature is supposed to add more clearance to code to show where |
… And not typehinting wouldn't be clear enough? No type hints === no specified type === throw in whatever you'd like. |
I am not going to argue with people who don't understand difference between mixed type and no type, sorry. Look at code that uses 7.1 and maintains BC for another X years. Example: class with 10 recently added methods with typehints, 10 old methods without anything to maintain BC. Now tell anyone whether mixed is intentional or not. |
There isn't a difference between no type and a mixed type. Intentional or not, old code will still accept any type, a.k.a. mixed type. If you're upgrading to php 7.2 I suggest you refactor code that ends up using type hints anyways. |
I'm not sure it's very good idea. You always can add comment to hint that type hint is ommited on purpose (with some inforation why it was done). With mixed type there will be situations when someone asks "please add type hints to your code" or there will be a requirement that code has to be with type hints and then a programmer will add massive amounts of "mixed" type hints - "because deadline". |
} | ||
} | ||
|
||
class Baz extends bar { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: bar
in lower case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bar
Bumping, would like to see that one in 7.3 if possible... Because I transformed a few of my interfaces to |
@Htarlov has very good point. Developers will just start adding mixed typehints mindlessly and everybody will think they are mixed by purpose. |
IMO it's the same really as typing nothing, except that if nothing is typed it really means "meh don't care". with the typehint, it's "tried to care, up to you to care to check". It's semantics, really. |
If anyone wants to shoot themselves into foot, it's their choice. Similar with Error, you can throw TypeError on your own although it's probably not a good idea. |
I still don't think it adds anything but bloat. It's functionality is none, it doesn't help the developer- nor PHP at all. Mixed is implicit if there is no type hint. It literally has no upsides at all. |
If nothing else, it forbids mixing
Quite the contrary: the developer instantly knows it's explicitly expected to accept/return mixed, instead of being forgotten type hint or legacy PHP
Don't forget that no return type means EITHER |
FYI: Based on the discussion and clearing up the inheritance issue with |
Published new version: https://wiki.php.net/rfc/mixed-typehint |
/* Child defines a type, but parent doesn't, violates LSP, unless it's a mixed type */ | ||
if (ZEND_TYPE_CODE(fe_arg_info->type) == IS_MIXED) { | ||
return 1; | ||
} | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this can be simplified:
return 0; | |
return ZEND_TYPE_CODE(fe_arg_info->type) == IS_MIXED; |
@@ -359,6 +362,9 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c | |||
if (proto->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { | |||
/* Removing a return type is not valid. */ | |||
if (!(fe->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { | |||
if (ZEND_TYPE_CODE(proto->common.arg_info[-1].type) == IS_MIXED) { | |||
return 1; | |||
} | |||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this can be simplified:
return 0; | |
return ZEND_TYPE_CODE(proto->common.arg_info[-1].type) == IS_MIXED; |
I would like to see this merged |
HUGE +1, would love to see this in PHP 7.4 or maybe 8.0, Example : <?php declare(strict_types=1);
interface Normalizer<T> {
public function normalize(T $data): array;
}
function foo(Normalizer<User> $normalizer, User $user): array {
return $normalizer->normalize($user);
}
function bar(Normalizer<string> $normalizer, string $data): array {
return $normalizer->normalize($data);
}
function baz(Normalizer<int> $normalizer, int $number): array {
return $normalizer->normalize($number);
} final class DefaultNormalizer implements Normalizer<mixed> {
public function normalize(mixed $data): array {
// code
}
}
$normalizer = new DefaultNormalizer();
foo($normalizer, new User()); // works
bar($normalizer, 'bar'); // works
baz($normalizer, 123); // works |
@azjeez Yes, it applies to generics in general, not just iterable or arrays. I'll make that clear in the RFC too. |
@Majkl578 , this should not be allowed with generics :
but i think |
@azjeez That's something up to the Generics RFC to define, in case mixed gets accepted. |
I would prefer having an or condition for multiple types instead of Most of the time its probably something like: /** @return string|bool */
public function foo(): mixed; So a declaration like would make more sense to me. public function foo(): string | bool; |
@kunicmarko20 exactly. Would prefer these types over |
As we now have union types, it probably makes sense to bring this up again. |
Isn't the main contention point as to whether it should include |
IMHO, function foo($bar): void {} is same as : function foo(mixed $bar): void {} note that hacklang already has another type called |
If we have union types, this doesn't solve any usecases anymore? |
@jordyvandomselaar With union types it becomes an alias, a sugar, similar to iterable or nullable types. The use case is still to express explicit interest in |
Note that it's not actually possible to write out a |
@Majkl578 but how would you have the compiler handle it? If you use something, would it complain that you have not handled any other type in your project that it might return? I use Laravel for example, should the compiler complain that I have not checked against a Laravel collection? I know TypeScript for example, tells me I forgot to check for null when using something that is nullable. |
@Majkl578 What's your plan with this? Will you propose |
This would be great indeed :) |
A My example is simple but it would be definitely better to write
Rather than
Which could be changed to
Without any error. Plus arguing that
And
Are the same, is like saying
And
Are the same. |
I think without |
} | ||
} | ||
|
||
class Baz extends bar { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bar
New implementation in #5313 has been merged, so closing this one. |
This is a proof of concept for built-in
mixed
type for parameter types and return types.The behavior of
mixed
type matches the behavior when no type is specified (thus being implicitly mixed).Primary motivation for having explicit
mixed
type is consistence and easier static analysis. In PHP 7.2, mixed types are unfortunately the only type that could not be type hinted upon (true, resource as well, but its future is unclear).I believe having
mixed
type would polish the code interface even more, thus having code with 100% explicit type hint coverage.Before:
Now:
(Note that I barely know the PHP internals so this may be entirely wrong approach.)
TODOs:
?mixed
at compile time?This probably needs an RFC, although mixed is already a reserved type. Since I don't have permission to create RFCs, a sponsor would be welcomed (anyone? 😇).
Not sure whether it'd be too late for inclusion in 7.2 in case it'd be accepted (probably not yet since there's not even a beta yet).
What do you think? 🚢