Re: Union Class Types (was Union Type (singular) straw man proposal)
| From: | Mike Schinkel | Date: | Sun, 08 Sep 2019 19:11:47 +0000 |
| Subject: | Re: Union Class Types (was Union Type (singular) straw man proposal) | ||
| References: | 1 2 3 4 5 6 7 8 9 10 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-106907@lists.php.net to get a copy of this message | ||
Hi Stephen,
Thanks again.
> So let me start out by clarifying that what *I* was suggesting with unions is quite a different
> concept than you’re talking about.
I did not realize you were proposing a different solution, too. Sorry I missed that.
> yes, I’m aware there’s potential ambiguous cases - what if the destination accepts
>
string|int and the object supports both interfaces?
Precisely. And the goal of my proposal was in part to eliminate that ambiguity.
> Ok - the example given makes “sense” with the understanding that it’s alternative
> ‘short’ syntax - but that makes it yet another step further from ‘intuitive’ to me, compared
> with current type hints, and the extension to allow unions Nikita introduced -
Acknowledged.
> and if Im not mistaken it makes it incompatible too (i.e. you can’t have the behaviour
> Nikita’s RFC describes and what you describe with the ‘anonymous unions’ - they’re too very
> different approaches using the same syntax.
I do not see how they are incompatible except for the details mine changes, but maybe that is moot
at this point?
> I think the intuitiveness factor is easier to explain if you consider the case of the Number
> example - plenty of things will work exactly as you expect if you use either an int or a float. But
> then with your proposal suddenly you don’t have a scalar variable any more - yes I know you can
> call value() - part of the point of type hints is to reduce
> boilerplate with type checking arguments within the function body - and now you have to call a
> method to get a usable value anyway?
I do not see any technical reason why mine would not be able to behave the same using the magic
methods you were proposing such as __toString() and for other scalar types — since fundamentally
the proposed union type would be a class anyway. When used that way it would nullify the benefit of
the explicit typing, but if that is what the developer wanted who was using then why not?
In that context it would be almost the same as just passing in a scalar.
> The GUID example still confuses me in terms of how your example ‘helps’. If
> $guid->getGuid returns null (signifying it’s a string?) presumably I still want to do something
> with that string - otherwise I wouldn’t have accepted it as a valid type - at which point I might
> as well just do a instanceof or
> is_string call - but now I have to check if the value I was given is
> null, even if I didn’t specify the parameter as being nullable?
It does not help that way. The main help is with $guid->type() which can be used in a switch.
It's just cleaner code, though I can appreciate that some might see this as not really a
benefit:
function processGuid(string|Guid $guid) {
switch( $guid->type()) {
case 'Guid':
$guid->toGuid()->doSomething();
break;
case 'string':
$g = new Guid($guid->toString());
$g-> doSomething();
break;
}
}
The other benefit is that it becomes a first-class concern that can be extended when named union
classes are used so I could implement this inside the union class and use it in many functions like
this, if I wanted, rather than have to use type checking boilerplate in Every. Single. Function:
class GuidUnion {
types string|Guid
public function doSomething() {
switch( $this->type()) {
case 'Guid':
$this->toGuid()->doSomething();
break;
case 'string':
$g = new Guid($this->toString());
$g-> doSomething();
break;
}
}
}
/**
* HERE is where you start seeing a real benefit...
*/
function processGuid1(GuidUnion $guid) {
$guid->doSomething();
}
function processGuid2(GuidUnion $guid) {
$guid->doSomething();
}
function processGuid3(GuidUnion $guid) {
$guid->doSomething();
}
> I think (or I hope so at least) we’re at least both clear what the other is talking about
> now.
Hopefully, with that last point clarified, yes.
Thanks again.
-Mike