On Thu, Dec 22, 2011 at 10:41:28AM -0800, Rasmus Lerdorf wrote:
> On 12/22/2011 07:08 AM, Keloran wrote:
> > i would love to see this expanded aswell (the way type hinting on function
> > variables was supposed to be), so that it could be
> > 
> > string, int
> > 
> > e.g.
> > function int test(bool $tester) {
> >  if ($tester) { return 5; }
> >  return 99;
> > }
> 
> Return type hinting needs to be aligned with parameter type hinting, and
> as has been pointed out many times on this list, type hinting for
> interchangable scalar types is a really bad idea. It will push all type
> checking up to the caller of the underlying functions/methods. PHP is
> primarily a Web scripting language and the Web isn't typed. Having stuff
> like this break:

I think that there are several problems with how we are discussing this:

a) we are confusing types with values.
   PHP variables contain caues and are juggled where needed, thus this works:
   $ten = '10';
   $eleven = $ten + 1;

   This is a great festure of PHP, works well in a web environment.
   We don't care if $ten is a string or an integer. We seem to call the
   type of this sort of variable a 'scalar'.

   In more complicated programs we might want to constrain the type of
   a variable - reduce surprise. The problem that we have is how to deal
   with the interface, eg when a value in a scalar variable is assigned
   to an integer variable. We have been thinking of these interfaces as being
   entry to functions (as arguments), something needs to happen at
   the interface. There are two ways:

       function test(int $value) ...

       test($ten)

    This would fail - since $ten is a string

        test($eleven)

    would work.

    We could make that value preserving in one of 2 ways, by the caller:

        test((int)$ten)

    That would work and give what we expect.
    We could also specify that the function do it:

        function test2((int) $value) ...

        test2($ten)

    Since $ten converts to integer cleanly.
    But:
        $fred = 'fred';
        test2($fred)
    would fail because you don't get clean conversion.

    This would be in the spirit of PHP today. The API specification of test2()
    would say that the argument must be numeric, ie the programmer must check it
    before passing it in -- but we are talking about the value, not the type in
    the strict manner.

b) the examples that we give are too simple. The benefits of knowing the type of
   something is greatest within a ''package'', we only need to do type checking 
at
   the package interfaces (the published API) and can assume correctness on 
internal
   calls. We do get potential speedups if we know a type we don't need to do 
type
   juggling checks at runtime, the could be done at compile time:

       function int MoreItems(int $items, (int) $more)
       {
           return $items + $more;
       }

    If a programmer does this then he will need to do explicit convertion:

        function string HowManyMore(int $items)
        {
            // A cast '(string)' is not needed since the compiler knows that 
$items is
            // int and so needs a convertion:
            return "You have bought another " . $items . " items";
        }

        function void AddAnother($another)
        {
            if( !preg_match('/^\d+$/', $another))
                throw new BadType("Another is bad");    // or something

            echo Howmany((int)$another);                // User convertion 
needed here

            // Cast not needed since it happens in the function definition
            $Total = MoreItems($Total, $another);       // $Total is defined 
somewhere
        }

        AddAnother($_POST['another']);

With bigger examples the advantages become apparent. But even the above is 
contrived
and simple.

> if(age_check($_POST['age'])) { do_stuff(); }
> 
> because the author of the age_check() function added an int type hint
> just doesn't make any sense. It would cause everyone to have to start
> casting things everywhere, just in case. eg.
> 
> if(age_check((int)$_POST['age'])) { do_stuff(); }
> 
> This is not a step forward. If the author of age_check() really doesn't
> want to accept type-juggled arguments, then it is easy enough to do a
> strict type check in the function itself. This puts the effort in the
> correct place and doesn't encourage this type of coding.

No: the check is an assertion against something that should never happen.
A programmer could do checks at every place where he thinks that it is needed
(ie at the package interfaces), but there is always the small possibility that
something slips through the net and causes mayhem - this will stop it.

The other reason for having type checking is that it allows PHP compilers such
as hip-hop to do more global optimisatons ... removing checking completely if it
knows everywhere a function (probably a class method) can be called from and 
knows
the types of the arguments that are passed in to it.

-- 
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT 
Lecturer.
+44 (0) 787 668 0256  http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: 
http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h>

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

Reply via email to