Hi!

> You can tell because you know the function foo expects an integer. So
> you can infer that $x will have to have the type integer due to the
> future requirement. Which means the expression "$something / 2" must
> also be an integer. We know that's not the case, so we can raise an
> error here.

OK, so your claim is that the compiler with strict typing can detect
some situations which the dynamic one can not and reject some of the
code. Without going too much into details, I agree with this, this is an
obvious difference between strict and dynamic. However, this is not a
performance advantage, obviously - since you are comparing running code
with non-running one - your model just accepts less code. Obviously,
this works if non-accepted code was wrong - and doesn't work if it was
not. But we talked about running code, I thought.

> At that point the developer has the choice to explicitly cast or put
> in a floor() or one of a number of options.

That's exactly what I claim would be the defect of the strict model -
people would start putting excessive casts ensuring there would be cases
where information is lost. For example, assume we knew $something is even:

function bar(int $something): int {
    assert($something %2 == 0);
    $x = $something / 2;
    return foo($x);
}

Now everything is fine (ignoring the typing for a second), right? We're
dealing with integers, /2 always divides evenly, all is great. Now we
introduce strictness, so we'd need to say something like:

function bar(int $something): int {
    assert($something %2 == 0);
    $x = $something / 2;
    return foo((int)$x);
}

Now assume somebody messed up on the routine code reformatting merge and
the code somehow ended up like:

function bar(int $something): int {
    $x = $something / 2;
    return foo((int)$x);
}

Do you see what the problem is? Now we lost the check for $something
being even, but we would never know about it since type system forced us
to insert (int) (which we didn't need) and thus disabled the controls
for the bug of $something not being even (which we did need).

But more important question is - with (int) the coercive model can use
this information too, so what's the difference from strict model on that
code? There seems to be none.

> Without strict typing this code is always stable, but you still need
> to generate full type assertions in a compiled version of foo() and
> use ZVALs for $x, hence reducing the effect of the optimization
> significantly.

Wait, you said "this code is invalid" so no code will be generated. Did
you mean code after introducing (int)? Then strict has no advantage
anymore as we can derive the info from (int) anyway.
Otherwise, I can't see how you can avoid generating typechecks in foo()
unless the only place it can ever be called from is bar() - but I don't
see how you can ensure that in PHP, and if you could, I don't see why
weak model could not make the same conclusions on the same code.

So far the only "advantage" I've seen seems to be that your compiler
would reject code that looks suspicious to it and thus force the
programmer to coerce the variables into the types manually - by (int) or
floor() - something that the coercive model would do for you
automatically. Once coerced, the same code would have the same type info
(and thus same potential optimizations) in both models. I don't think it
is a gain in general, and I don't think forcing people to modify their
code qualifies as "JIT performance gain".
-- 
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