rfc:scalar-pseudo-type

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
rfc:scalar-pseudo-type [2017/12/24 15:20] – created fleshgrinderrfc:scalar-pseudo-type [2017/12/24 23:33] (current) – Added object to the analogous list of other types fleshgrinder
Line 10: Line 10:
  
 ===== Proposal ===== ===== Proposal =====
-This RFC proposes a new ''scalar'' pseudo-type. This type is analogous to ''callable'' and ''iterable'', accepting multiple types instead of one single type.+This RFC proposes a new ''scalar'' pseudo-type. This type is analogous to ''callable''''iterable'', and ''object'', accepting multiple types instead of one single type.
  
 ''scalar'' accepts ''bool'', ''float'', ''int'', and ''string''. All of these types can be safely coerced to a ''string'' and be printed. ''scalar'' accepts ''bool'', ''float'', ''int'', and ''string''. All of these types can be safely coerced to a ''string'' and be printed.
Line 81: Line 81:
  
 The function [[https://php.net/is-scalar|is_scalar]] to determine whether a value is ''scalar'' or not already exist in PHP since a long time and must not be added. The function [[https://php.net/is-scalar|is_scalar]] to determine whether a value is ''scalar'' or not already exist in PHP since a long time and must not be added.
 +
 +====== Weak Mode ======
 +Objects with a magic ''toString'' method are accepted and treated as strings in weak mode. The behavior is 1:1 the same as if the type constraint would have been ''string'' in the first place for objects. This ensures perfect consistency and adheres to the principle of least astonishment.
 +
 +====== Examples ======
 +======= Scalar Parameters =======
 +PHP core already contains a multitude of procedures that could be constrained to ''scalar'' instead of ''mixed''.
 +
 +<code php>
 +function strpos(string $haystack, scalar $needle, //...
 +function printf(string $format, scalar ...$args): string {}
 +// ... and many, many, many more ...
 +</code>
 +
 +However, it is also useful in userland.
 +
 +<code php>
 +interface Parser {
 +    /** @return static */
 +    function parse(scalar $input);
 +}
 +</code>
 +
 +<code php>
 +namespace Userland\Database\MySQL;
 +
 +class ReadConnection {
 +    private $mysqli;
 +
 +    function fetch(string $query, ?scalar ...$args): ResultSet {
 +        $types = '';
 +        
 +        foreach ($args as $arg) {
 +            if (is_float($arg)) {
 +                $types .= 'd';
 +            } elseif (is_bool($arg) || is_int($arg)) {
 +                $types .= 'i';
 +            } else {
 +                $types .= 's';
 +            }
 +        }
 +
 +        //...
 +        $stmt->bind_params($types, ...$params);
 +        //...
 +    }
 +}
 +</code>
 +
 +In other words, it allows one to implement type safe method overloading over a well-defined set of types. It does not cover all possibilities just one common one. (Covering all possibilities is not possible anyways and would require union types.)
 +
 +======= Scalar Returns =======
 +The return type constraint is less commonly useful than the one for parameters, however, it is specifically of interest while designing supertypes for others and to work around the magic ''toString'' method that can only return values of type ''string'' (and is incompatible with exceptions).
 +
 +<code php>
 +interface Convertible {
 +    function into(): scalar;
 +}
 +
 +final class Longitude implements Convertible {
 +    /** @var float */
 +    private $deg;
 +    
 +    //...
 +    
 +    function into(): float {
 +        return $this->deg;
 +    }
 +}
 +
 +// In combination with our previous DB example.
 +$db->fetch('SELECT * FROM t WHERE lng = ?', (new Longitude(42.42))->into());
 +</code>
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
rfc/scalar-pseudo-type.1514128815.txt.gz · Last modified: 2017/12/24 15:20 by fleshgrinder