Why I don’t think type-hinted foreach loops are a good idea

There was a Twitter poll going around this morning that I thought was kind of interesting and got me thinking.  It asked whether or not type-hinting in a foreach loop would be a good idea.  The argument was that the same arguments that go for have type hinting in functions/methods apply to loops.  Those reasons would primarily be structure.  Having a more rigid structure means that the likelihood of a runtime error is lessened to a much greater degree.  I agree with this statement, but I don't think that it applies to loops.  And here's why.

The structure argument makes complete sense in the function/method definition.  That is because an individual function has a defined unit of functionality.  Therefore, requiring a certain type of data may  be necessary to implement that specific piece of functionality.

However, this is not the same with a loop.  The only purpose of a loop is to iterate over data.  The example given is

foreach($array as $key => MyClass $a)

I am assuming that when you iterate over the array that if an array item is not an instance of MyClass that PHP would fail in the same way that it does when you run into a function with a different declaration.  Besides the fact that an array is a generic data structure, what happens if this failure occurs during a series of database inserts or updates?  Or a series of web service calls?  IMHO, a loop is a generic structure that does one thing: iteration.

That said, there is actually a construct that I would be open to.

foreach(MyCollectionClass $array as $key => $a)

Then you could have code like this

class MyClass {}

class MyCollectionClass extends ArrayIterator
{
    public function append($value)
    {
       if (!$value instanceof MyClass) {
           throw new Exception("Invalid class added to collection");
       }
       parent::append($value);
    }

    public function offsetSet($index, $newval)
    {
        if (!$newval instanceof MyClass) {
           throw new Exception("Invalid class added to collection");
       }
       parent::offsetSet($index, $newval);
    }
}

What this does is enforce typing prior to the loop iteration and protects against invalid data in the loop.  But this could just as easily be written

if ($array instanceof MyCollectionClass) {
    foreach( $array as $key => $a) {
    }
}

What do you think?

Related posts

4 thoughts on “Why I don’t think type-hinted foreach loops are a good idea

  1. Marten van Urk

    I think it’s step too far.
    You should control the type when pushing data in the array and not afterwards.

  2. Kevin Schroeder

    Agreed, but if people absolutely wanted some kind of type checking in a foreach loop, checking the source variable type and not the element variable type makes much more sense to me. Though the best option would be to just leave it as is, IMHO.

  3. You fixed your comments here 😀 (preview maybe?) – I think doing a cast is interfering with the iterator pattern which is implemented in foreach.

    Doing the array cast drastically limits the use of the iteration because it gets binded to a certain type on outbound instead of dealing with proper types on each iteration.

    On consequence is that the nice SPL iterator stuff get’s broken with such array casts.

    I would therefore consider it bad practice in PHP to do casting in foreach.

  4. ChrisAustralia

    Well then please tell my IDE to stop showing errors inside the figgin foreach loop :-/
    phpStorm daaang!

Leave a Comment