Hi,

Fleshgrinder wrote:
On 3/16/2016 5:36 PM, Phil Sturgeon wrote:
2. This whole temporary nullability situation, where unset properties
will error on attempted usage if not set. Should they instead error
after the constructor has been called if they are still not holding a
value?


I see a big problem with the erroring no matter when as others already
pointed out, e.g. together with named constructors (or factory methods
if you prefer that name) but also with lazy loading. I think that the
null value of properties during and after construction should simply be
ignored and left to the implementer. I know that it would be nice to
have 100% assurance that the property is always set but it would simply
result in rules that are too strict for various use cases. I mean,
aren't we trying to solve a problem that never was a problem here?

This is actually a problem for optimising PHP. If the compiler cannot be sure a property's value actually matches its declared type, it can't optimise operations on that property to remove a type check.

I also think it would be unintuitive if typed properties had some exception where they don't obey the given type. If I ask for an integer, then surely I should get an integer?


Another more complicated user case would be *mysqli_fetch_object* that
populates the properties with values from a storage but values that
should become something specific and strict at some point but are
initially populated as strings. Type coercion would be a nice thing here
but with strict checks afterwards. Note that this cannot be handled by
the extension due to user types:

     final class Bar {

         private string $data;

         public function __construct(string $data) {
             $this->data = $data;
         }

     }

     final class Foo {

         private Bar $bar;

         private function __construct() {
             if (isset($this->bar)) {
                 $this->bar = new Bar($bar);
             }
         }

     }

     $mysqli_result->fetch_object(Foo::class);

It is correctly populated with a string and the constructor changes it
to the desired instance. All fine, but the strict type check would kill
everything here.

I think that the strict type checks should start with the first
*userland* assignment and at no other point in time. The correct
initialization of an object is up to the implementer as it always was.

This adds a loophole to property type checks which, as previously mentioned, prevents us from performing optimisations. I also don't see why internal functions should be treated specially here, given that surely one could write userland code with the same needs as MySQLi? It doesn't seem intuitive.

On 3/16/2016 6:27 PM, Chris Riley wrote:
[...] how about some syntax which allows for a property to be null,
or for it to be a specific type. I'd suggest a null assignment to
fall in line with parameter type hints eg:

class Foo {
     protected int $bar = null; //can be null
     private stdClass $baz; //can't be null
}


This aligns nicely with the syntax that is present in PHP for arguments
since ages and it directly could solve the Nullable problem mentioned in
future scope.

We could certainly do this, but I'm not sure we should. Like for arguments, this would mean that your default value must be null, and you don't have to assign to it. But what if you want a different default value? What if you want to require it be assigned to?

Adding a syntax form for nullable types (e.g. `?int` or `int|null`) would avoid these issues, and also solve the nullable return type issue.



On 3/16/2016 5:36 PM, Phil Sturgeon wrote:
3. Weak vs Strict. Right now this is entirely strict, with no
declare() to change mode. Reasons for this vary, from various sources,
but include "Not sure how to implement it" and "Well people should not
be using properties as part of their public API".


An ini setting to control type checks and hints would be a nice thing to
have.

An INI setting to control type checks is impractical, because it would affect all PHP code running in a given PHP interpreter. This means you control not only the type checking mode of your own code, but also of all the libraries you're using. Unless you never use other people's code, using this INI setting would just break things.

Like the checked mode of Google's Dart language. Such a setting
could and should also allow to disable type checks altogether, like we
have it with assertions:

     strict_types = -1 ; NOOP
     strict_types = 0  ; PHP 5 Style
     strict_types = 1  ; PHP 7 Coercion Style
     strict_types = 2  ; PHP 7 Strict Style

Why would you want to disable type checks altogether? There might be a small performance improvement, but you've removed important error checking. What if something goes wrong at runtime?

Where 1 would be the default since the default should be for development
and people who hate strict types just throw that zero in their ini and
are fine to reuse any code out there while ignoring all property/scalar
type checks/hints.

This solves a problem which I don't believe exists. The system PHP 7 has means that if you don't want to use strict types, they never affect you.


This would make the `declare` thingy pretty useless and I think it is
easier to understand. I thought that this approach was kind of weird
since its inception.

Yes, the declare() approach is unusual compared to other settings. That's because it was designed so the choices your code makes doesn't affect other code which uses it. In the Composer era, this matters, because a lot of code your interpreter is running will not be written or maintained by you.

Thanks.

--
Andrea Faulds
https://ajf.me/

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to