On 4/22/2016 4:15 AM, Sara Golemon wrote: > All that said, I love the proposal overall, and I can't wait to > propose builtin annotations like <<__Memoize>>, <<__Mock>>, and > similar. >
I'd rather see these two functionalities added as modifiers at the language level instead since they change the code behavior rather dramatically. Not sure if knowledge of them is of interest in stages where annotations might not be readily available; this was a driving factor in Kotlin's decision what becomes a modifier or annotation.[1] <?php final class A { private memoized function f() {} } test class B extends A { // OK, despite final. public function f() {} // Has access to private methods. } test class C extends B {} // OK class D extends B {} // Fatal Error! ?> I know that this is true for `@invariant`, `@require`, and `@ensure` as well, they are fully-fledged assertions after all. Especially the `@invariant` could be easily added as a magic method. [assert] assert.invariants = 1 <?php final class Object { public function __invariant() {} } ?> Both `@require` and `@ensure` are a bit harder to implement at language level. The following is the best I can come up with and is inspired by the Eiffel syntax.[2] [assert] assert.preconditions = 1 assert.postconditions = 1 <?php class PreconditionError extends AssertionError {} class PostconditionError extends AssertionError {} final class Account { public function withdraw(int $sum): void { $this->balance -= $this->balance - $sum; } require { $sum >= 0; $sum <= ($this->balance - self::MIN_BALANCE); } ensure { $this->balance === (old::$balance - $sum); } } $account = new Account; $account->withdraw(-10); /* Uncaught PreconditionError: $sum >= 0 */ $account->withdraw(10); /* Uncaught PreconditionError: $sum <= ($this->balance - self::MIN_BALANCE) */ $account->deposit(10); $account->withdraw(5); /* Uncaught PostconditionError: $this->balance === (old::$balance - $sum) */ ?> I actually think now that it would be better to go for this than for annotations. [1] http://blog.jetbrains.com/kotlin/2015/08/modifiers-vs-annotations/ [2] https://archive.eiffel.com/doc/online/eiffel50/intro/language/invitation-07.html -- Richard "Fleshgrinder" Fussenegger
signature.asc
Description: OpenPGP digital signature