I'm working on a framework that I'm trying to type as strongly as I possibly can.  (I'm working within PHP and taking some of the ideas that I like from C# and trying to utilize them within this framework.)  I'm creating a Collection class that is a collection of domain entities/objects.  It's kinda modeled after the List<T> object in .Net.
I've run into an obstacle that is preventing me from typing this class.  If I have a UserCollection, it should only allow User objects into it.  If I have a PostCollection, it should only allow Post objects.
All Collections in this framework need to have certain basic functions, such as add, remove, iterate.  I created an interface, but found that I couldn't do the following:
interface ICollection { public function add($obj) }
class PostCollection implements ICollection { public function add(Post $obj) {} }
This broke it's compliance with the interface.  But I can't have the interface strongly typed because then all Collections are of the same type.  So I attempted the following:
interface ICollection { public function add($obj) }
abstract class Collection implements ICollection { const type = 'null'; }
class PostCollection {
 const type = 'Post';
 public function add($obj) {
  if(!($obj instanceof self::type)) {
   throw new UhOhException();
  }
 }
}
When I attempt to run this code, I get syntax error, unexpected T_STRING, expecting T_VARIABLE or '$' on the instanceof statement.  A little research into the issue and it looks like the root of the cause is that $obj instanceof self is valid to test against the class.  It appears that PHP doesn't process the entire self::type constant statement in the expression.  Adding parentheses around the self::type variable threw an error regarding an unexpected '('.
An obvious workaround is to not make the type variable a constant.  The expression $obj instanceof $this->type works just fine (if $type is declared as a variable, of course).
I'm hoping that there's a way to avoid that, as I'd like to define the value as a constant to avoid any possible change in the variable later.  Any thoughts on how I can achieve this, or have I take PHP to it's limit in this regard?  Is there a way of "escaping" or encapsulating self::this so that PHP won't die when processing it?