On 04/07/2016 03:44 PM, Bob Weinand wrote:
Hey,
Am 6.4.2016 um 10:45 schrieb Dmitry Stogov <dmi...@zend.com
<mailto:dmi...@zend.com>>:
Hi Jow,
First of all, I appreciate the amount of effort you already invested
into this idea.
Anyway, I still don't agree with the following terms of RFC and
corresponding implementation:
1) While parameters allow null to be accepted as the default value,
null is never a valid value for a typed property.
I think we must have a way to make properties explicitly nullable.
Otherwise we won't be able to define even simple binary tree...
class Node {
public Node $left = null;
public Node $right = null;
}
Eventually that, but I honestly would prefer to be more explicit with
a typed union
public Node | null $left;
This is not a subject of this RFC. This is about "union types" vs
"nullable types".
2) The implementation will raise an exception where a typed property
is accessed before being initialized: <https://3v4l.org/cVkcj/rfc#tabs>
This makes unnecessary complication, and opens thousands
possibilities to cheat the engine.
class A {
public int $x;
}
$a = new A;
var_dump($a->x++); // prints NULL (according to RFC, this should
raise Exception)
I propose to initialize typed properties with the value of
corresponding type (if default value is omitted).
boolean => false
int => 0
double => 0.0
string => ""
array => []
object, resource, callable => null
Actually, I propose implicit default values if they are not specified.
This will always guarantee the type and eliminate run-time checks on
read.
The things being pre-initialized is quite defeating the purpose.
It’s possibly not to easy from an engine perspective, but it is the
safest thing to do from a type systems perspective.
Also, it is creating useful invariants that a value cannot be null
(also for optimizer).
Default values for scalars and arrays obviously work, but still, they
will hide bugs if you forgot to assign a property.
3) It is possible to unset typed properties, and return them to the
same state as a property that was never set.
This mean that properties types are not guaranteed, and
Optimizer/Compilers/JIT won't be able to generate the best code
performing type check on every read.
I would prefer to disable unset() of typed properties.
Property types are guaranteed,
Check the patch. ZEND_FETCH_OBJ_R opcode.
it will just throw an exception when used (it’s a branch which is
never used, thus relatively cheap). Also that pretty much conflicts
with your point 2) where you propose null as a default value,
enforcing a hard type check (which won’t be easy to predict for branch
predictors).
I don't propose NULL to be a default value. I propose to allow nullable
properties, in the same way as arguments (only for data that really need
this).
So "public int $a;" is always going to be "int", nor NULL or UNDEF. And
you won't need to endlessly check it for is UNDEF.
4) Checking the type of a zval is an extremely cheap operation, there
may be some very minor performance impact only when typed properties
are used.
The patch makes some slowdown even if typed properties are not used
(0.5% more instruction retired on 100 requests to Wordpress according
to callgrind)
Feel free to optimize it, but possibly we’ll get much more gain than
0.5% on projects which are going to heavily use it.
This "possibly" makes my cry :(
I'm sure, this will make only slow-down.
Just try to add arg/return type hints to bench.php and see the result.
5) In principle, knowing the type of a variable in advance allows you
to make optimizations, and in the long term, there is good reason to
think that typed properties will allow us to improve performance.
This is an optimistic assumption
For now typed-parameters make slowdown except of expected speedup,
properties are not going to change this.
Actually the type of property may make some gain only if we know the
type of object and its definition at compile-time, but in most cases
we do't know the class definition, because definition and usage are
in different PHP scripts.
Especially with (2) and (3), even if we know type of object and
property, we'll still have to check if property is initialised on
each usage.
A lot of optimizable code is inside the classes themselves though
(private properties). I don’t guess it’s too optimistic? With typed
properties and typed input vars, computing functions will be very
optimizable I guess.
don't guess, try and prove!
Also regarding not-null properties, we may have to check the type of
the property only once for the whole method instead of on every access
inside that method.
no. because it may be unset() or reassigned.
Thanks. Dmitry.
Bob
Thanks. Dmitry.
------------------------------------------------------------------------
*From:* Dmitry Stogov
*Sent:* Wednesday, April 6, 2016 10:32
*To:* Joe Watkins
*Subject:* Typed properties patch
Ho Joe,
I see some tests failures (SIGSEGV)
> Test typed properties float widen at runtime
[Zend/tests/type_declarations/typed_properties_027.phpt]
> Test typed properties respect strict types (off)
[Zend/tests/type_declarations/typed_properties_028.phpt]
> Test typed properties unset __get magical magic
[Zend/tests/type_declarations/typed_properties_030.phpt]
valgrind shows problems on every 4-rd test at Zend/tests (454 of 1668
tests), but it seems like a single problem
$ cat ../Zend/tests/add_002.mem
==26053== Conditional jump or move depends on uninitialised value(s)
==26053== at 0x8627895: _zend_object_has_type_hints
(zend_execute.h:367)
==26053== by 0x8629098: zend_std_write_property
(zend_object_handlers.c:674)
==26053== by 0x85FA1B5: zend_update_property (zend_API.c:3894)
==26053== by 0x85FA38E: zend_update_property_string (zend_API.c:3952)
==26053== by 0x860F8DB: zend_default_exception_new_ex
(zend_exceptions.c:222)
==26053== by 0x860F96F: zend_default_exception_new
(zend_exceptions.c:236)
==26053== by 0x85F347E: _object_and_properties_init (zend_API.c:1303)
==26053== by 0x85F34B5: _object_init_ex (zend_API.c:1311)
==26053== by 0x86124F4: zend_throw_exception (zend_exceptions.c:881)
==26053== by 0x85EF256: zend_throw_error (zend.c:1316)
==26053== by 0x85E4622: add_function (zend_operators.c:969)
==26053== by 0x868824E: ZEND_ADD_SPEC_CV_CV_HANDLER
(zend_vm_execute.h:44246)
Thanks. Dmitry.
Bob