Hi!

> It is still a performance advantage, because since we know the types
> are stable at compile time, we can generate far more optimized code
> (no variant types, native function calls, etc).

I don't see where it comes from. So far you said that your compiler
would reject some code. That doesn't generate any code, optimized or
otherwise. For the code your compiler does not reject, still no
advantage over dynamic model.

> Actually, in this case, the int cast does tell us something. It says
> that the result (truncation) is explicitly wanted. Not to the compiler
> (tho that happens), but to the developer.

No, it doesn't say that in this case. The developer didn't actually want
truncation. They just wanted to call foo(). You forced them to use
truncation because that's the only way to call foo() in your compiler.
They said it's ok since truncation is over value that is int anyway, and
they are true - except when it stops to be true in the future. That
generates brittle code because it forces the developer to take risks
they otherwise wouldn't take - such as use much stronger forced
conversions instead of more appropriate dynamic ones.

> With coercive typing as proposed in Ze'ev's RFC, that would need to
> happen anyway. In both proposals that would generate a runtime error.

No, it wouldn't need to happen since no-DL conversion is allowed.

> The difference is, with strict types, we can detect the error ahead of
> time and warn about it.

Static analyzer can warn about it regardless of type model. The only
difference in strict model is that when compiling - not ahead of time,
but in runtime - it would produce hard error even in case of even
number, which can work just fine without it.

> In this precise example there is none, because division is not type

That's what I am saying - if the code runs, there's no difference. The
only difference your model runs less code, and forces (or, rather,
strongly incentivizes) people to wrote more dangerous one because some
of the non-dangerous one is not allowed.

> stable (it depends on the values of its arguments). Let's take a
> different example
> 
> function foo(float $something): int {
>     return $something + 0.5;
> }
> 
> With coercive types, you can't tell ahead of time if that will error
> or not. With static types, you can.

I'm not sure what this proves. Yes, of course there are cases where
strict typing (please let's not confuse it with static typing - these
are different things, static typing is when everything's type is known
in advance and this is not happening in PHP, that's kind of the whole
point) would disallow some code that dynamic typing allows. Nobody
argues with that. What I am arguing with is that this difference is
somehow useful - especially for JIT optimizations.

> No, I was talking about trying to do the same trick (using native
> function calls) with coercive types.

I'm not sure what you are comparing to what. You provide some code and
say "in my compiler, this code A would not work, while in dynamic model
it would. Instead, you should write code B. This code B would run faster
in my compiler". But that is not a proof your compiler is better!
Because code B would also run faster in dynamic model, and in addition,
code A would also run (though indeed not faster than B).

> Actually, no. Coercive as proposed by Ze'ev would cause 8.5 to error
> if passed to an int type hint. So you'd need the cast there as well.
> Either that, or error at runtime as well.

We were talking about the case where the argument was even, you must
have missed that part. If the argument is not even, indeed both models
would produce the same error, no difference there. The only difference
in your model vs. dynamic model so far is that you forced the developer
to do manual (int) instead of doing much smarter coercive check on
entrance of foo(). There's no performance improvement in that and
there's reliability decrease.

> Hence, in both cases casts would be required. One could tell you ahead
> of time where you forgot a cast, the other would wait until runtime
> (when the edge-case was hit).

You imply it's always the case of "forgot" and the casts always should
be there, which is not the case - actually, as I already said, I think
this is the main defect of your model, forcing manual casts everywhere.
Otherwise, I agree - that's the only difference. Still struggle to see
any JIT gain. So far only one advantage demonstrated was the obvious one
- if you obviously pass obvious non-int to int parameter in strict
model, this can be detected statically. It would be stupid to deny that
as it is pretty much immediately follows from the definition of strict
model. But that's the only difference I see and not much of an advantage
in my eyes as a) patently obvious cases would be pretty rare and b) in
many cases would also not be what developer wanted, leading to manual
casts and c) last but not least, static analyzer doing that can be as
easily written without having these strict rules in core PHP!

> Sure it does. If their code is not type-stable, even simply telling
> them that can give advantages both in performance and in correctness.

OK, so I got it right and the "JIT advantage" was in fact not in JIT
working better but in static analyzer forcing people to write the code
that looks more JIT-friendly by rejecting some of the code that does
what developer wants but the compiler/analyzer can't figure it out? But
nothing prevents you from having the same JIT-friendly code in the first
place, moreover - nothing prevents you from having static analyzer that
generates alerts on code that you think may be non-JIT friendly and let
the developer decide if that's what they want. All that does not require
strict typing at runtime in any form.

I of course completely disagree in correctness part - I think making
people use forced conversions (which are OK with data loss in many
cases) is worse than using smarter coercive typing.

> Their code is buggy today. All the static type system does is show it
> to them ahead of time, rather than relying on test failures or bugs to
> show it.

You seem to be talking about static type system, but PHP has no static
type system and strict typing of function parameters does not introduce
one.

> And to be fair I haven't really been talking generic JIT, but generic
> AOT (which can include local-JIT compilation).

Even for AOT, I don't see any advantage for strict typing on the same
code. The only difference is that strict AOT compiler would reject some
code and some of that code may be non-JIT-friendly. On accepted code,
again, I see no difference.
-- 
Stas Malyshev
smalys...@gmail.com

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

Reply via email to