rfc:dbc2

This is an old revision of the document!


PHP RFC: Native DbC support as definition

Important Note

This RFC is a part of “Native DbC support” RFC. http://wiki.php.net/rfc/dbc

There are many way to achieve DbC. This RFC proposes DbC as function/method definition.

Introduction

Design by Contract (DbC) or Contract Programming is powerful program design concept based on Contracts that

  1. Define precondition contract for methods/functions. i.e. Define Parameter value specifications/conditions.
  2. Define postcondition contract for methods/functions. i.e. Define Return value specifications/conditions.
  3. Define invariant contract for methods/functions. i.e. Define class state must be true always.

These contracts are evaluated development time only. Therefore, there is no performance penalty with DbC.

DbC changes the way program is designed.

  • With modularized design without DbC, the more code is consolidated, the better code is. Therefore, parameter validity is checked deep into the code. Parameter validity check is calleE responsibility.
  • With DbC, parameter checks are done as precondition. Passing valid parameter to a function is calleR responsibility.
  • Without native DbC, return value validity cannot be checked without scattered assert() for every place function is used. i.e. Programmers has to write “$ret = func(); assert($ret > 0);” everywhere func() is used or func() must have assert() for every return.
  • With native DbC, return value validity is checked as postcondition definition. It does not require scattered assert().
  • With native DbC, invariant condition may be defined. Invariant allows programmers consolidate class state which must be TRUE for always. e.g. $account_balance >= 0

precondition check can be done with assert(), but other feature requires native DbC.

DbC reverses the responsibility caller and callee, ensures parameters, return value and class state validity without performance penalty. This helps PHP to achieve more efficient development by contract errors, faster execution for production.

With proper use of DbC concept, it is known programs to be more robust/secure and faster. Languages design lately have native DbC support. e.g. D language. Almost all languages have some kind of DbC supports today.

Proposal

Introduce native contracts “require”(precondition), “return”(postcondition) definition to function/method and special “invaliant()” method to class. require, return behave just like assert(). (require, return accepts message. i.e. require($a > 0, '$a must be positive') ) Example without invariant <code php> class Product { protected $inventory; User is supposed to check inventory first function haveEnoughInventory($quantity) require($quantity > 0) { return (bool) ($this->inventory - $quantity) >= 0; } Sell inventory function sell($quantity) require($quantity > 0) return($ret >= 0) We have to think of how to specify $ret. Use block? return($ret) {assert($ret >= 0);} { $ret = $this>amount - $quantity; return $ret; } } </code> Example with invariant <code php> class Product { protected $inventory; Invariants must be TRUE for this class always - $inventory should not be negative function invariant() {

  assert($this->inventory >= 0);
}
// User is supposed to check inventory first
function haveEnoughInventory($quantity) 
  require($quantity > 0)
{
  return (bool) ($this->inventory - $quantity) >= 0;
}
// Sell inventory
function sell($quantity) 
  require($quantity > 0)
{
  return $this>amount - $quantity;
}

} </code>

Execution Control

Introduce “dbc” INI switch, Off by default. No additional CLI option for DbC.

A method/function is executed as follows

Development mode: dbc=On

  1. require() conditions
  2. invariant() - method() - invariant()
  3. return() conditions

Production mode: dbc=Off

  1. method()

Backward Incompatible Changes

None

  • No additional keyword
  • __invariant() is a reserved method name

Proposed PHP Version(s)

  • PHP7

RFC Impact

To SAPIs

None

To Existing Extensions

None

To Opcache

Dmitry, could you write impact when discussion is finished?

New Constants

None

php.ini Defaults

dbc=Off for all

  • hardcoded default values
  • php.ini-development values
  • php.ini-production values

Open Issues

  • Need to discuss syntax
  • How to manage votes for 2 RFCs

Unaffected PHP Functionality

This RFC does not affect any existing features

Future Scope

Documentation systems may adopt native DbC syntax for documentation purpose.

Proposed Voting Choices

Include these so readers know where you are heading and can discuss the proposed voting options.

State whether this project requires a 2/3 or 50%+1 majority (see voting)

Patches and Tests

Links to any external patches and tests go here.

If there is no patch, make it clear who will create a patch, or whether a volunteer to help with implementation is needed.

Make it clear if the patch is intended to be the final patch, or is just a prototype.

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Rejected Features

Keep this updated with features that were discussed on the mail lists.

rfc/dbc2.1423520591.txt.gz · Last modified: 2017/09/22 13:28 (external edit)