Type-dispatch methods

  Status: draft
  • Created: 2009-11-17 10:07:20+0100
  • Categories: <core>
  • Target: 5.8.0
  • Author: friebe

Scope of Change

Methods will be allowed to have variants of themselves with different type signatures.


Rationale

Code simplification.

Functionality

Instead of having one method with a big if / else block inside, we will allow declaring separate methods, each with their type literals embedded.

Declaration

Current:

  public function setXml($xml) {
if ($xml instanceof Tree) {
// A
} else if (is_string($xml)) {
// B
}
}

New:

  public function setXml·Tree($xml) {
// A
}

public function setXml·þstring($xml) {
// B
}

Dispatch

Dispatch will be performed at runtime, except if a compiler / code preprocessor can determine exactly.

Here's an example of a generated dispatcher method:

  #[@dispatch]
public final function setXml() {
static $overloads= array(
1 => array(
'setXml·Tree' => array('!Tree'),
'setXml·þstring' => array('!string'),
),
);

$args= func_get_args();
foreach (@$overloads[sizeof($args)] as $method => $signature) {
foreach ($signature as $i => $literal) {
if (NULL === $args[$i]) {
if ('!' === $literal{0} || !strstr($literal, '.')) continue 2;
} else {
if (!Type::forName(substr($literal, 1))->isInstance($args[$i])) continue 2;
}
}
return call_user_func_array(array($this, $method), $args);
}

raise
(
'lang.MethodNotImplementedException',
'No overload for ['.implode(', ', array_map(array('xp', 'typeOf'), $args)).']',
'setXml'
);
}



Reflection

Reflection will list one method, "setXml" in this case. A reflective invocation will also apply dispatch logic.

Security considerations

n/a

Speed impact

TODO

Dependencies

RFC #0197

Related documents

Comments



<EOF>


Table of contents