In the [[http://portal.acm.org/citation.cfm?id=1353491|StrongAspectJ paper]], the authors consider this example as a case for separate "proceed signatures": Integer around(): //(1) call((Integer || Number) *()): Number proceed() { //(2) return new Integer(proceed().intValue()); //(3) } In this example, the advice declares an "advice signature" (1) that returns Integer objects but a "proceed signature" (2) that returns any Number objects. This allows the advice to be applied to any method returning *any* type of Number while at the same time guaranteeing that only Integers are returned. ===== What could this look like in JPIs? ===== One could capture this semantics with a syntax such as: jpi A Number()-> Integer(); Here, ''Number()'' is the "expected interface", i.e., the ''proceed'' interface, while ''Integer()'' is the provided interface. ===== Generic Advice ===== Another example given in the StrongAspectJ paper is the following: N around(): call((Integer || Float) *(..)): N proceed() { N n = proceed(); while(n.intValue() > 100) n = proceed(); return n; } Here the generic type parameter ''N'' is used to refer to any concrete return type (here ''Integer'' or ''Float'' of ''Number''). Using the type parameter instead of just directly using ''Number'' has the advantage that one knows that the advice *will* return an ''Integer'' if a method call returning an ''Integer'' is advised but also *will* return a ''Float'' if a method call returning an ''Float'' is advised. In JPIs one could model this as: jpi A N()-> N(); Such a jpi could then be applied to calls such as... Long l = System.currentTimeMillis(); ... while the jpi ''jpi A Number()-> Number()'' could only be applied in cases where the method returns a value of type Number.