Hello internals,

I've been thinking about this as an RFC for awhile, but with generics
being far off (if at all), I'd like to propose a useful idea: reusing
the AS keyword in a different context.

Example:

$x = $attributeReflection->newInstance() as MyAttribute;

This would essentially perform the following code:

assert(($x = $attributeReflection->newInstance()) instanceof MyAttribute);

but would work even if assertions are disabled, and would provide some
sanity when working with mixed return types, or even dealing with
interfaces where you want to be sure you are dealing with a concrete
type:

class Query implements QueryInterface {}

function getQuery(string $sql): QueryInterface {}

$x = getQuery("select 1 = 1") as Query;

which is more like:

assert(($x = getQuery("select 1 = 1")) instanceof Query);

It'd also be nice to have a non-throwing version where we simply
specify that the type is nullable:

$x = $attributeReflection->newInstance() as ?MyAttribute;
if ($x === null) // do something since the attribute isn't MyAttribute

which is more like:

try {
  assert(($x = $attributeReflection->newInstance()) instanceof MyAttribute);
} catch {
  $x = null
}

Or a more complex type:

$x = $attributeReflection->newInstance() as
PretttyAttribute|(UglyAttribute&UtilityAttribute);

Essentially, by using "as", you can be 100% sure that the type is the
expected type signature, null (if the type signature includes null),
or an error to be thrown.

Note that this isn't casting from one type to another, but asserting
that this type is the type you expect. It'd significantly help with
static analysis, IDE code completion, etc.

What do you think?

Robert Landers
Software Engineer
Utrecht NL

Reply via email to