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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to