Drafting out an RFC for "strict"

I’m posting this here before I actually put this up on the PHP RFC forum, to get feedback on it and whether or not it should even be pursued, bothering the devs of PHP. Also, a co-sponsor or two wouldn’t hurt.

This is a draft

PHP RFC: Strict and Tolerant Variables

Introduction
The vast majority of PHP program bugs and security exploits are due to the language’s loose data typing. While such is a strength for the language in terms of ease of use and especially helping novice programmers along by removing yet another thing to worry about and learn, it can create headaches, especially when PHP needs to interface with other programs that do not support loose data types, especially databases.

Proposal
Allow programmers to explicitly set the data type in one of two fashions: tolerant or strict. The only difference between them is how they behave when values of the wrong datatype are assigned to them. Tolerant variables silently cast any incoming data to their own data type. Strict variables throw a catchable fatal error when an attempt is made to assign a variable of the wrong type to them. Both types must be explicitly declared - for backwards compatibility PHP must assume any variable declared on the fly is a scalar.

Here is the syntax of declaring these variables.

/*
 * Tolerant variable creation looks like casting and allows many of the same 
 * casts: int, integer, bool, boolean, float, double, real, string, array, 
 * object
 */
var (int) $a; 
var (float) $a = 3.14;

/*
 * Strict variables use brackets as well.
 */
var ([int]) $c = 9;
var ([bool]) $toggle = false;

Syntax within array and class declarations is similar

$b = [
  ([int]) 6,
  (bool) true,
  ([string]) hello
];

class A {
  public (int) $z = 9;
  protected ([string]) $y = "up";
}

In addition to the type casts, specific objects can be required. To satisfy the requirement the incoming value must either be the class specified, inherit from it, or implement it.

var ([PDO]) $db;

Strict and tolerant variables that haven’t been given a value yet are null.

These variables affect type juggling in the following ways. First when compared to a scalar, the scalar must change type to match them. This makes comparison operations somewhat more predictable. When compared to each other their datatypes must match or the condition is false. Hence comparing these variables is always a strict comparison.

var ([int]) $a = 3;
var ([int]) $b = 6;
$c = '6';

($b == $c); // true - $c is forced to convert to integer.
($b === $c); // false - scalars cannot change datatypes during strict comparison.
($a < $b); // true - further this is a strict lesser than comparison, something PHP cannot currently do.

Function arguments can be made strict or tolerant as well on a per argument basis…

function( (int) $a, ([float]) $b) { ... }

And the return can be strict or tolerant…

public function myMethod( ([int]) $a, ([int]) $b)([int]) { ... }

Interfaces can be made useful this way by forcing their implementers to return a certain type!

interface myInterface {
  protected function foo ( ([int]) $a, ([int]) $b )([bool]);
}

Cause right now the usefulness of PHP interfaces is somewhat dubious precisely because of this lack.

Backward Incompatible Changes
None I think. Even if someone foolishly named a class “string” the \ operator can be used to allow casting of variables to that object, as distinct from the string type.

Proposed PHP Version(s)
As far reaching as this would be a major version change is the only one suitable, so PHP 7.

Ok, that’s it I think. I’m not trying to make PHP something it is not - this is an “opt in” strong data typing system, so those who prefer loose data typing can continue to use it.

One thing this opens the door to that isn’t included in this proposal is overloading functions - functions who’s names are the same but are distinguished by their data types. Given that scalars will still be around and likely the most common variable type, I think including that functionality is just asking for trouble.

Thoughts and comments welcome.

1 Like

Somewhat related reading: http://blog.krakjoe.ninja/2014/11/strictly-research.html

Don’t forget that SPL already has SPL Types that can be used for strong typing, type hinting, etc. If you need an option for strong typing, why not build on that rather than create a completely new and excessively complex syntax?

You’re also trying to implement return type hinting, which has gone through several different RFCs, that you haven’t mentioned, but some of which even support multiple return types like Boolean|integer (such as the return for strpos()

Interested to know if there is a patch for this idea, I prefer code to ideas ?

It’s worth mentioning I think, that this is going to be met with resistance, here’s why …

Quote Rasmus:

PHP is and should remain:

  1. a pragmatic web-focused language
  2. a loosely typed language
  3. a language which caters to the skill-levels and platforms of a wide range of users

This text is part of the RFC template for PHP, we have to pay attention whatever our personal preference might be.

The problem is that while this is optional, so are classes, autoloaders, access modifiers on properties, type hints and just about everything else that is propping up this modern ecosystem. It’s safe to assume that this will penetrate the ecosystem, people will choose to use it and it’s arguable this would result in changing PHP from a dynamic language.

I’ve done much playing around in this area, I’m not sure of the best solutions myself, there is currently an RFC in draft by Andrea to introduce scalar type hints that coerce user function parameters in the same way as internal function parameters are coerced, I’m not sure what kind of traction any of these ideas will get, it’s interesting to watch whatever.

1 Like

But if you still want strict typing, remember that Hack is still out there for you.

<?hh
class MyClass {
  const int MyConst = 0;
  private string $x = '';
  public function increment(int $x): int {
    $y = $x + 1;
    return $y;
  }
}

Yeah, hack is tempting. As to the odd syntax, I was trying to insure no new keywords would be needed

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.