Personally, I do not like when a function return multiple types. Yet, PHP built-in functions do return multiple types as well (yikes!) and some people were hoping TSPHP does allow a return-false-if-something-goes-wrong approach as well somehow.
Just as a side notice, there exist PHP built-in functions which return bool/int (strpos), bool/string (strstr), bool/resource (fopen) and bool/DateTime (date_create) and most probably further combinations. The important part here, this approach is not restricted to scalar types.
At the moment, one can return multiple types by specifying mixed as return type but it implies that one has to apply casts every time one wants to work with the return value. Although, that does not sound convenient, TSPHP is designed this way on purpose to steer the user in the right direction: do not return several types which have nothing in common. Therefore, I do not intend to support other types than bool as additional type. Everything else hampers the readability too much and goes against the goal readability of TSPHP (see Vision of TSPHP). Hence, the following code is not under discussion to simplify somehow.
If you code this way and you do not think about to change your style then type safety is maybe not what you are looking for.
Following an example of a return-false-if-something-goes-wrong approach which is part of this discussion (in contras to the example above).
This topic relates to scalar type hierarchy
Following some thoughts on how to support the return-false-if-something-goes-wrong approach in TSPHP:
TSPHP could specify that each type can hold bool. The code would look as follows:
TSPHP could introduce a modifier which defines that a type can also hold false (is falseable). Could look as follows:
TSPHP could introduce that one can restrict mixed somehow. Could look as follows
TSPHP does not support this approach and the user has to create a wrapper for this purpose (could use generics later on). With generics it could look like this
If TSPHP should support overload for __construct then it could be simplified a little bit.
The code where Falseable would be used would look as follows
Last but not least, I want to point out that everyone could do the same job by returning null instead of false which has more or less the same effect (not if null is a valid value of course). Or they could throw an exception if something goes wrong (that works always). Therefore it might well be that I am not going to change anything (especially if no one submits a feature request explicitly).
Pros and cons
Every type can hold bool
+ user does not have to think about it (more the PHP way)
- Goes somewhat against type safety (yet, one can argue mixed as such goes against type safety as well and if mixed is ok then this approach would be ok as well)
- Cannot be regulated with code conventions (the usage of the other constructs could be forbidden in code conventions)
+ Pretty much like Nullable which defines that a certain type can hold null in addition.
+ Can easily be forbidden in code conventions
- Might be too comfortable, user do not see that it is rather bad design to return two things (yet, others might see this point different and it is restricted to false only and finally the modifier ! somehow screams to watch out )
mixed can be restricted to certain types
+ Looks rather ugly, people might reconsider before returning two types
+ Can easily be forbidden in code conventions
- Is like a bad syntax choice for point 2 but
+ Is still better than only mixed (safer in a manner of type safety) could be extended to arbitrary types and number of types
- somehow a conflict between type safety and readability. It favours type safety because it is safer than mixed but it also encourage users to return multiple types which is against type safety
- complex to implement especially with an arbitrary number of types -> thus only allow it for return types. That means variables can only be of type mixed (not mixed<x,y>) and complexity would still be fairly simple.
User has to create a wrapper
+ no additional complexity in TSPHP core
+ As you can see the code looks rather ugly and one does consider twice before using such a construct
- only for people who do OOP, functional programming would not have such a construct
- most probably, there will be several different implementations in user land (unless they stick to the implementation here or this implementation is provided in a standard TSPHP library)
TSPHP wil go for variant 2 since it enhances readability - one of the goals of TSPHP (see Vision of TSPHP). Furthermore it enables the decision in scalar type hierarchy. See - TSPHP-820Getting issue details... STATUS for more information