In the 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 extends Number> 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 <N extends Number> 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.