Re: [RFC] Scalar Type Hints v0.2
| From: | Andrea Faulds | Date: | Thu, 15 Jan 2015 14:20:08 +0000 |
| Subject: | Re: [RFC] Scalar Type Hints v0.2 | ||
| References: | 1 2 3 4 5 6 7 8 9 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-80538@lists.php.net to get a copy of this message | ||
Hey Rowan,
> On 15 Jan 2015, at 13:02, Rowan Collins <rowan.collins@gmail.com> wrote:
>
> Zeev Suraski wrote on 15/01/2015 11:56:
>> PLUS have the ability to radically
>> change how it behaves based on a runtime option. It's so bad that we
>> decided more than a decade ago that we want to refrain from ever introducing
>> such elements to PHP again (e.g. magic_quotes_runtime), and I'm not sure why
>> we're even discussing it.
>
> Just on this point, I do think declare() is potentially less evil than ini_set() / php.ini. A
> declare() directive is scoped to a particular section of code, so library authors shouldn't
> need to care which setting their users prefer, only the version they themselves wish to use. This
> contrasts completely with things like mbstring.func_overload, which makes shared library code run
> differently in different configurations.
Yeah, that’s the idea behind it. The hope is that you could have strictly-typed and weakly-typed
code interact seamlessly with minimal issues. And, for the most part, this should allow that.
A large part of the motivation behind this was avoiding the problems that adding separate strict and
weak hints would have. Inevitably, people who were fans of weak typing would use a weak hint all the
time, and people who were fans of strict typing would use a strict hint all the time. There would
also be the odd few who might mix them, but I don’t think that would happen terribly much.
It’s much easier to deal with this:
foo(1.0, 1); // strict
$qux = bar(“foo”); // also strict
foobar($qux, baz(true)); // also strict
or this:
foo(1.0, 1); // weak
$qux = bar(“foo”); // also weak
foobar($qux, baz(true)); // also weak
Than it would be to have to deal with this:
foo(1.0, 1); // weak
$qux = bar(“foo”); // strict
foobar($qux, baz(true)); // baz is strict, foobar is weak
This RFC would guarantee that, for the most part, you’re dealing with the first case (strict mode)
or the second case (default). I fear that separate strict and weak hints would result in the third
case being commonplace.
I was also worried that if we just added weak hints, people who didn’t like them would not use
them and instead use manual assertions. Similarly, I think something similar might happen if we just
added strict hints. In both cases, you would be ending up with the third situation. Also bear in
mind that if we added strict hints and did not change the behaviour of extension and built-in PHP
functions, we’d also be dealing with that third situation, since zend_parse_parameters essentially
does a kind of weak typing.
Of course, this RFC does still lead to dealing with both weak and strict modes sometimes, but at
least it’d always be the same mode within a given file, and by extension, within a given function,
method or class. I think that’s more practical than dealing with two or more different modes
within three lines of code.
> As has been clarified elsewhere on this thread, under this proposal a library author writing
> function foo(int $foo) will ALWAYS receive an integer, regardless of how that integer is arrived at.
> Very approximately, the declare() directive effectively gives the caller a choice between two pieces
> of syntactic sugar, both of which guarantee that the callee's contract will be met:
>
> if ( is_int($foo) ) { foo($foo); } else { raise_type_error($foo); }
>
> or
>
> foo ( (int)$foo );
>
> So, just to repeat, this is NOT like register_globals or mbstring.func_overload, because shared
> code never needs to handle both settings.
>
> That's not to say I'm 100% convinced that this is the right way to go, just that
> it's not as abominable as some people are making out.
Right.
--
Andrea Faulds
http://ajf.me/