As alluded to in an earlier email today1 I am now moving the Union
Types RFC2 to the discussion phase. The short summary of the RFC is
that it permits a type declaration to be one of several enumerated
types. For example, this is a potential signature for a multi-type map
routine:
function map(callable $f, Array | Traversable $iterable);
The second parameter $iterable
is required to be of type Array or
Traversable - any other type will error.
I look forward to a helpful and meaningful discussion!
The RFC doesn't say anything about support for multiple class names.
function foo(A|B|C $x)
Support for multiple classes would lead to complex implementation.
Thanks. Dmitry.
I think this will add more complexity to the runtime system. The type
hinting will be something we use to generate good JIT code, not just for
checking types.
Dmitry Stogov dmitry@zend.com 於 2016年4月14日 星期四寫道:
The RFC doesn't say anything about support for multiple class names.
function foo(A|B|C $x)
Support for multiple classes would lead to complex implementation.
Thanks. Dmitry.
From: Levi Morrison <morrison.levi@gmail.com javascript:;>
Sent: Thursday, April 14, 2016 06:46
To: internals
Subject: [PHP-DEV] [RFC] Union TypesAs alluded to in an earlier email today1 I am now moving the Union
Types RFC2 to the discussion phase. The short summary of the RFC is
that it permits a type declaration to be one of several enumerated
types. For example, this is a potential signature for a multi-type map
routine:function map(callable $f, Array | Traversable $iterable);
The second parameter
$iterable
is required to be of type Array or
Traversable - any other type will error.I look forward to a helpful and meaningful discussion!
--
--
--
Sent from Gmail Mobile
As alluded to in an earlier email today[1] I am now moving the Union
Types RFC[2] to the discussion phase. The short summary of the RFC is
that it permits a type declaration to be one of several enumerated
types. For example, this is a potential signature for a multi-type map
routine:function map(callable $f, Array | Traversable $iterable);
I think what I am missing in the RFC is behaviour with scalar (weak)
typehints, and which type the variable in a class would be converted to.
Take for example:
function foo(int|bool $var) { echo get_type( $var ), "\n"; }
foo(5); I guess int(5)
foo(false); I guess bool(false)
foo(0.5); It could be either int(1) or bool(true)
And what if the hint would be "bool|int" ?
Although it's probably easy enough to solve in this case, the RFC should
detail how type conversion works with the scalar types.
cheers,
Derick
I think what I am missing in the RFC is behaviour with scalar (weak)
typehints, and which type the variable in a class would be converted to.
Take for example:function foo(int|bool $var) { echo get_type( $var ), "\n"; }
foo(5); I guess int(5)
foo(false); I guess bool(false)
foo(0.5); It could be either int(1) or bool(true)And what if the hint would be "bool|int" ?
I think type conversion shouldn't be done internally, implicitly.
Implicit conversion leads more confusion in the language. when you pass
variables, you have to remember these conversion rules.
type conversion should be done in the caller, that's why typed language
like C or C++ ask you to convert the type manually before you pass the
variable into a function.
--
Best Regards,
Yo-An Lin
I think what I am missing in the RFC is behaviour with scalar (weak)
typehints, and which type the variable in a class would be converted to.
Take for example:function foo(int|bool $var) { echo get_type( $var ), "\n"; }
foo(5); I guess int(5)
foo(false); I guess bool(false)
foo(0.5); It could be either int(1) or bool(true)And what if the hint would be "bool|int" ?
I think type conversion shouldn't be done internally, implicitly.
Implicit conversion leads more confusion in the language. when you
pass variables, you have to remember these conversion rules.
Sorry, we already have this with our weak scalar types. You can't make
union types not work with that.
cheers,
Derick
As mentioned in my nullable types comment, I think that we should NOT add a
Null type unless the nullable types RFC fails to pass. We should not
introduce both options, and I favor the nullable types over this for that
purpose.
With regards to Dericks comment on type conversion, I think either simply
casting to the first type always, or we're going to have to come up with
some potential complex rules.
For example, what if you have: int|float, and pass in (string) "0.5", if
those were separate types you'd get (int) 1, or (float) 0.5 respectively,
and as a user I'd definitely expect it to be passed in as (float) 0.5 —
maybe we cast to the least lossy type? So if you have int|float, then a
numeric string always becomes a float.
The flip-side is that if we just decide first-always then it's up to the
developer to just define it as "float|int" instead.
I think Derick has definitely hit upon the trickiest part of this.
Also, just to clarify, if you combine this with the nullable types syntax
(assuming prefix), then the nullable applies to the entire union type:
?int|float === int | float | null
I do find the shorter syntax confusing TBH.
Which actually leads me to a different thought: defining custom types and
using them instead.
I very much like Hacks type/newtype stuff, if we extended that to support
union types:
newtype Numeric = int|float;
Then you end up with simply: ?Numeric as your type (it should be
namespaced).
You could further expand that with casting rules:
newtype Numeric = int|float {
string as float;
bool as int;
}
or even go so far as:
newtype Numeric = function($value): int|float {
if ($value typeof int) {
return $value;
}
return (float) $value;
}
FTR: I hate that last one, just spitballing.
- Davey
P.S.
if someone is willing to tackle the code for custom types I'm willing to
write an RFC
I think what I am missing in the RFC is behaviour with scalar (weak)
typehints, and which type the variable in a class would be converted
to.
Take for example:function foo(int|bool $var) { echo get_type( $var ), "\n"; }
foo(5); I guess int(5)
foo(false); I guess bool(false)
foo(0.5); It could be either int(1) or bool(true)And what if the hint would be "bool|int" ?
I think type conversion shouldn't be done internally, implicitly.
Implicit conversion leads more confusion in the language. when you
pass variables, you have to remember these conversion rules.Sorry, we already have this with our weak scalar types. You can't make
union types not work with that.cheers,
Derick
Also, just to clarify, if you combine this with the nullable types syntax
(assuming prefix), then the nullable applies to the entire union type:?int|float === int | float | null
I do find the shorter syntax confusing TBH.
Which actually leads me to a different thought: defining custom types and
using them instead.I very much like Hacks type/newtype stuff, if we extended that to support
union types:newtype Numeric = int|float;
Then you end up with simply: ?Numeric as your type (it should be
namespaced).You could further expand that with casting rules:
newtype Numeric = int|float {
string as float;
bool as int;
}or even go so far as:
newtype Numeric = function($value): int|float {
if ($value typeof int) {
return $value;
}return (float) $value;
}
FTR: I hate that last one, just spitballing.
- Davey
P.S.
if someone is willing to tackle the code for custom types I'm willing to
write an RFC
This issue is addressed partially in the future scope section of the
RFC: https://wiki.php.net/rfc/union_types#long_type_expressions.
If both nullable and full union types are allowed I was planning on
disallowing the short-hand notation when using unions. As it isn't
that relevant at this stage it isn't noted in the RFCs anywhere.
Derick Rethans derick@php.net 於 2016年4月14日 星期四寫道:
On Thu, Apr 14, 2016 at 5:12 PM, Derick Rethans <derick@php.net
javascript:;> wrote:
I think type conversion shouldn't be done internally, implicitly.Implicit conversion leads more confusion in the language. when you
pass variables, you have to remember these conversion rules.Sorry, we already have this with our weak scalar types. You can't make
union types not work with that.
Does Hack support weak type conversion?
--
Sent from Gmail Mobile
As alluded to in an earlier email today[1] I am now moving the Union
Types RFC[2] to the discussion phase. The short summary of the RFC is
that it permits a type declaration to be one of several enumerated
types. For example, this is a potential signature for a multi-type map
routine:function map(callable $f, Array | Traversable $iterable);
I think what I am missing in the RFC is behaviour with scalar (weak)
typehints, and which type the variable in a class would be converted to.
Take for example:
This is not missing in the RFC; see the section called Weak Scalar
Types in Open Issues. However, it does not propose a solution. I have
been assured by a few people that it is possible and it is just
something that needs worked out.
Den 2016-04-14 kl. 16:25, skrev Levi Morrison:
As alluded to in an earlier email today[1] I am now moving the Union
Types RFC[2] to the discussion phase. The short summary of the RFC is
that it permits a type declaration to be one of several enumerated
types. For example, this is a potential signature for a multi-type map
routine:function map(callable $f, Array | Traversable $iterable);
I think what I am missing in the RFC is behaviour with scalar (weak)
typehints, and which type the variable in a class would be converted to.
Take for example:
This is not missing in the RFC; see the section called Weak Scalar
Types in Open Issues. However, it does not propose a solution. I have
been assured by a few people that it is possible and it is just
something that needs worked out.
Should the discussion phase lead to proposed conversion
rules in the RFC for scalar types or is it left for later?
Regards //Björn
I think it will be better if union type is only allowed in the "type"
statement, like what you described in your RFC.
type Iterable = Array http://www.php.net/array | Traversable;
If we can always pre-define the types.
And only allow just one type for each function parameter in the function
prototype, then, I think the performance impact of type checking in the
runtime might be able to be reduced.
In other words, you predefine the union type before you used them, and the
union types can be reused in different functions, you don't write a lot
union type in function prototype.
Hi! You are everywhere :P
2016-04-17 6:28 GMT-04:00 Lin Yo-An cornelius.howl@gmail.com:
I think it will be better if union type is only allowed in the "type"
statement, like what you described in your RFC.type Iterable = Array http://www.php.net/array | Traversable;
If we can always pre-define the types.
And only allow just one type for each function parameter in the function
prototype, then, I think the performance impact of type checking in the
runtime might be able to be reduced.In other words, you predefine the union type before you used them, and the
union types can be reused in different functions, you don't write a lot
union type in function prototype.
Performance issues aside, the ability to inline type expressions on
function signatures --- function myMethod(A|B $arg){...} --- can be "nice"
because it allows us to keep type definitions private. Assuming that a
named type could be reused by third party code (as public API) and that may
not always be the intended.
Of course this would be much better addressed with first class packages
where interfaces, classes, types etc can have their visibility defined. But
until we get there, having the type expressions on argument lists may be
useful.
Cheers,
Márcio
As alluded to in an earlier email today1 I am now moving the Union
Types RFC2 to the discussion phase. The short summary of the RFC is
that it permits a type declaration to be one of several enumerated
types.
I look forward to a helpful and meaningful discussion!
Hi Levi,
Your email 1 excellently summarizes the overall historical and present
context. In it you listed three specific things that 7.0 cannot
represent. My RFC[3] basically argues in favor of implementing only the
first of these in 7.1. I like to see this as a more conservative version
of yours, preferring a more gradual introduction of these three
loosenings of PHP 7.0's type features.
[3] https://wiki.php.net/rfc/nullable_returns
I hope you will consider this a constructive contribution to the discussion.
Tom