troels knak-nielsen wrote:
1) It covers all the use cases for a type-based system (You can use
`is_integer` as a contract, if you want that)
2) It's extensible in user-space, which means that it can be used to
convey much more accurate information, relevant to the application
needs.
3) It's focused on the interface of input-parameters, rather than their type.

This is my favorite alternative so far. There are just a few problems with parsing as I see it.

 - How do you know if it is a contract or the current object type hint?
 - It doesn't allow a type to be forced (casted) to the correct type.

To address these items, I suggest the following changes.

Change the syntax of the contract to look like a function call (which is essentially what we are doing):

  <?php
  function array_of_numeric($x)
  {
      if (!is_array($x)) {
          return false;
      }
      foreach ($x as $val) {
          if (!is_numeric($val)) {
              return false;
          }
      }
      return true;
  }

  function sum(array_of_numeric($a)) {
      return array_sum($a);
  }

This could even be extended to allow for more generic types by allowing constant parameters for the contract:

  <?php
  function array_of($x, $type)
  {
      if (!is_array($x)) {
          return false;
      }
      switch ($type) {
          case 'int':
              $check = 'is_int';
              break;
          case 'float':
              $check = 'is_float';
              break;
          case 'numeric':
              $check = 'is_numeric';
              break;
          case 'string':
              $check = 'is_string';
              break;
          case 'bool':
              $check = 'is_bool';
              break;
          default:
              return false;
      }
      foreach ($x as $val) {
          if (!$check($val)) {
              return false;
          }
      }
      return true;
  }

  function sum(array_of($a, 'numeric')) {
      return array_sum($a);
  }

To allow for casting, the contract function could take the value by reference and cast it:

  <?php
  function array_of_float(&$x)
  {
      if (!is_array($x)) {
          return false;
      }
      foreach ($x as $key => $val) {
          if (!is_numeric($val)) {
              return false;
          }
          $x[$key] = (float)$val;
      }
      return true;
  }

  function sum(array_of_float($a)) {
      return array_sum($a);
  }

--
Joshua Thompson
Mechanical Engineer/Software Developer
http://www.schmalls.com

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

Reply via email to