> domain SymfonyPermission: string;
> domain AcmePermission: string { 'admin' | 'user' | 'bot' };
> [...]
> Domains can also be considered sets, which you could compare directly,
> and maybe even calculate intersections, unions, etc:
>
> The actual values would be ordinary strings, and type constraints would
> just be checking the value passed against the domain:
>
> Crucially, this solves the described problem of a library accepting an
> infinite (or perhaps just very wide) set of values, and a consuming app
> wanting to constrain that set within its own code.
>
> It's one disadvantage is the typo-proofing and look up availability that
> constants give, but you could always combine the two.
>
Thanks for this idea Rowan, that's really interesting.
I would go one step further and require naming the values in the set.
Borrowing from the syntax of enums, we could have:
set AcmePermission: string {
case ADMIN = 'admin';
case USER = 'user';
case BOT = 'bot';
}
Then AcmePermission::ADMIN would === 'admin' and, as you said,
AcmePermission could be used as a type on functions:
function (AcmePermission $perm): AcmePermission
{
$perm instanceof AcmePermission; // true
return $perm;
}
In order to make this work, we would need to be able to autoload the type
AcmePermission.This could be done by the type-checking logic: when checking
$var against AcmePermission and the type is undefined, if $var is an int or
a string, call the autoloader for 'AcmePermission'.
There are other things to consider, like possible changes to reflection,
whether such a set also declares a class like enums do, etc.But overall, I
really like it and I agree with you: this would provide a really good
solution for the problem ppl try to use enums for.
I don't know how we could move forward on that idea. By starting another
thread?
Nicolas