Before I begin, and without picking on anyone specific, I want to say that
it is generally unhelpful to say that because I, or others, do not know how
the engine is set up that it is impossible to make any meaningful
contributions to the list or on this issue specifically.  My clients don't
understand HTML.  If I told them they needed to study how HTML works before
trying to give me input on the sites I'm building for them I'd likely be
fired.  As a theater major I know quite a bit more than most of the people
on this list about what makes a good play or movie actually work, but I
don't pretend that knowledge is prerequisite to knowing if a play or movie
is good.  It either works, or it doesn't.

If the fallback to all suggestions is "Shut up, that's impossible to do
given current engine architecture." then I'm afraid that PHP is doomed to
become the next COBOL - a language with a lot of important legacy programs,
but no new developers or future as those old systems finally give up the
ghost. Also, given that HHVM has implemented at least one aspect if this
proposal with classes the argument that it's impossible carries a rather
large spoonful of salt.

This said, I will refrain from offering any more input on how this might be
implemented as it is clearly not wanted. I will instead focus on the
desired end state.


Much of what follows is based on Michal Brzuchalski's comments.  His
commentary can be largely summed up with "using the var keyword in a
counter-intuitive way is just going to make matters worse. Also,
getter/setter debates are quite a bit out of scope.



Third Draft.

Target version: PHP 8.

This is a proposal to strengthen the dynamic type checking of PHP during
development.

Note - this is not a proposal to change PHP to a statically typed language
or to remove PHP's current typing rules. PHP is typed the way it is for a
reason, and will remain so subsequent to this RFC. This RFC is concerned
with providing tools to make controlling variable types stronger when the
programmer deems this necessary.



DEFINITIONS
Before a meaningful discussion on types and type handling can be performed
some terms must be defined explicitly, especially since their definitions
in common parlance may change from language to language, and even
programmer to programmer. I

* Static Typing: This typing is performed by the compiler either explicitly
or implicitly.
* Dynamic Typing: This typing is performed by the runtime. Unlike static
typing it allows for varying degrees of variable coercion.
* Strong/Weak typing: These terms typically refer to the amount of latitude
the run time has to coerce variables - the more latitude the "weaker" the
typing.



VARIABLE DECLARATION (GLOBAL AND FUNCTION SCOPE)

PHP currently has no keyword to initialize a variable - it is simply
created when it is first referenced. The engine continually coerces the
variables into the required types for each operation. While this is a very
powerful ability, it runs into problems with comparisons (
http://phpsadness.com/sad/52 ). As a result of this issue PHP (and many
languages that share this problem such as JavaScript) provides the strict
comparison operator.  Avoiding this issue is one reason it can be useful to
have some amount of control over a variable's type. This can be
accomplished with two keywords, one old and one new: var and strict.

var $a = 5;
strict $b = 9;

Together these are "mutability operators" - that is they control if a
variable can mutate, be coerced, recast or what have you between types. The
strict keyword removes the mutability of a variable between types. The var
keyword restores it. The keywords perform these operations even in the
absence of an assignment, though using strict without any assignment will
lead to an error since type will be unknown.  Examples.

var $a; // $a will be created and be NULL.
strict $a; // TypeError - strict variables must have an explicit type or a
value from which a type can be inferred.
$b = 5;
strict $b; // $b locks down to integer since it was already declared. It's
value remains 5.
var $b; // $b's ability to be coerced is restored.
strict int $c; // Works. $c will be empty - any assignment must be the
specified type.
strict $d = 'Hello'; // Works. Type of string can be inferred.

Both keywords allow comma delimited lists of declarations (for
consistency), but strict will be the one to use it most frequently:

strict $a = 1, $b = "Hello", $c = 3.14, $d = [];

$a is inferred to int, $b to string, $c to float and $d to array.



FUNCTION DECLARATION

The strict keyword in a function declaration locks down the argument var
for the remainder of the function (or until var is used). For consistency
it is recommended that var be allowed as well, but it wouldn't do anything
beyond cuing IDE's that mixed will be accepted.

function foo (strict int $a, strict string $b, var $c, strict $d = true) {}



ARRAYS
If an array is strict all of its keys and values will be strict and
inferred on assignment.

strict $a = [
  'id' => 1,
  'name' => 'Mark',
];




CLASS MEMBERS

The var keyword appeared in PHP 4 to declare class members and found itself
deprecated. As the mutability operator it is still allowed, and now allowed
alongside the scope operator.

class SomeClass {
  var $a = '3';
  public var $b = 'hello';
  public strict $c = 3.14;
  protected strict int $d;
}

Interfaces can also lock member types following the above pattern.




COMPARISON BEHAVIOR
As mentioned above comparisons are the area where the most stability gains
are to be had. When strict variables are compared to dynamic or "var"
variables only the var variable will be coerced. If two strict variables
are compared a TypeError will raise barring an explicit cast

strict $a = 123;
strict $b = '123';

if ($b == (string) $a) {}

Reply via email to