Re: [RFC] Scalar Type Hints v0.2

From: Date: Mon, 02 Feb 2015 16:30:42 +0000
Subject: Re: [RFC] Scalar Type Hints v0.2
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
Hi Dmitry,

> On 2 Feb 2015, at 09:24, Dmitry Stogov <[email protected]> wrote:
> 
> > Will we able to call the same function using weak
> > type hinting from on file and with strict from the other?
> 
> Yes, for the parameter type hints anyway. That means that strict and weak code is interoperable
> without enforcing a model on each other.
> 
> At first I thought, this is ugly solution. Now I'm not completely sure.

I did as well when I first saw the idea proposed (someone else originally suggested it). It does
seem ugly on the surface, but it has some advantages. Sure, you have to add this extra line of code
to each file, that’s annoying. But, it means full backwards-compatibility, easier migration of
existing codebases, and most importantly, allows people to choose one mode or another without
affecting other users that have to call their code.

> I see, but this would require declare(strict_types=1) everywhere that would turn PHP into Java.

Well, not quite Java, but yes. Typing it out is annoying. But it’s better than implicit strict
typing for a directory, and it means we avoid having two or three different kinds of scalar type
hint, so there’s no mixing of systems within the same file.

After a while I think people will get used to it. PHP programmers already have to type out
"<?php namespace foobar;” at the start of each file, Perl programmers need
"#!/usr/bin/perl” and “use warnings; use strict”, JS programmers need “(function () {
‘use strict’; }());” etc. Also, IDEs would help.

> > Strict type hinting is not suitable for PHP by definition (as a weakly
> > typed language), however, I see, it may be useful in some cases.
> > I would prefer to have "weak" types at first, then think about introducing
> > ability to switch to "strict" type hinting in context of use-cases.
> 
> That'd be possible, but I fear that we'd just end up with weak typing only and no
> strict solution. Regardless of its merits, a large portion of the community is in favour of a
> strictly-typed solution. There are also a lot of people who are in favour of weak typing. So, this
> RFC tries to make a compromise.
> 
> I see, but I afraid that compromise is worse than one or the other.

I’m actually convinced that this compromise is in some ways better than one or the other.

One of the nice things about strict mode only applying to code which asks for it, is that if a
function if an API has type hints added, it won’t suddenly break calling code that didn’t
strictly match types, if that calling code uses the default weak mode behaviour (which it will if it
was written pre-PHP 7).

For example, say I have some sort of Response object that lets you set a body:

    class Response {
        public function setBody($message);
    }

In PHP 5, it’s perfectly fine to pass something that’s not a string for $message:

    $foo = new Response;
    $foo->setBody(67);

Absurd example, but this sort of thing does happen in real world code, often accidentally.

Now, let’s say we add a string type hint in a new version of the library:

    interface Response {
        public function setBody(string $message);
    }

If PHP’s type hints were always strict, then our existing PHP 5 code from earlier that took
advantage of PHP’s weak typing would now produce an error:

    Catchable fatal error: Argument 1 passed to Response::setBody() must be of the type string,
integer given

This isn’t good - it makes migration of the existing codebase difficult.

Weak typing solves this problem because it allows conversions. However, it’s not really good that
the code was passing an integer in the first place - it should really be passing a string.

The solution, then, is what this RFC offers. By default, weak typing is used, so your existing code
doesn’t break initially. But once you’ve added type hints in a few places, you can switch to
strict typing, and that error will be detected and can be fixed.

This way, we can have stricter types without sacrificing compatibility or complicating migration.

Thanks.
--
Andrea Faulds
http://ajf.me/






Thread (148 messages)

« previous php.internals (#81597) next »