Is there a function which accepts a reference to a lambda expression and returns a boolean saying whether the lambda expression is stateless or not? How can the statefulness of a lambda expression be determined?
While AWS Lambda's programming model is stateless, your code can access stateful data by calling other web services, such as Amazon S3 or Amazon DynamoDB.
A stateful lambda expression is one whose result depends on any state that might change during the execution of a pipeline. On the other hand, a stateless lambda expression is one whose result does not depend on any state that might change during the execution of a pipeline.
The above execution model makes Lambda functions effectively stateless. This means that every time your Lambda function is triggered by an event it is invoked in a completely new environment. You don't have access to the execution context of the previous event.
A stateful operation is the one whose result depends on any state that might change during the execution of the pipeline. Stateless operations retain no state during the execution of the pipeline.
Well, a lambda expression is just an instance of a special anonymous class that only has one method. Anonymous classes can "capture" variables that are in the surrounding scope. If your definition of a stateful class is one that carries mutable stuff in its fields (otherwise it's pretty much just a constant), then you're in luck, because that's how capture seems to be implemented. Here is a little experiment :
import java.lang.reflect.Field;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
final StringBuilder captured = new StringBuilder("foo");
final String inlined = "bar";
Function<String, String> lambda = x -> {
captured.append(x);
captured.append(inlined);
return captured.toString();
};
for (Field field : lambda.getClass().getDeclaredFields())
System.out.println(field);
}
}
The output looks something like this :
private final java.lang.StringBuilder Test$$Lambda$1/424058530.arg$1
The StringBuilder
reference got turned into a field of the anonymous lambda class (and the final String inlined
constant was inlined for efficiency, but that's beside the point). So this function should do in most cases :
public static boolean hasState(Function<?,?> lambda) {
return lambda.getClass().getDeclaredFields().length > 0;
}
EDIT : as pointed out by @Federico this is implementation-specific behavior and might not work on some exotic environments or future versions of the Oracle / OpenJDK JVM.
No, it is not generally possible. The suggested approach of checking whether the lambda belongs to a class with a field is the next best thing, but having a field does not equal having a state.
class Stateless {
int result = 0;
public int getResult() { return result; }
}
It is possible to prove statefulness by finding two input sequence for which a given input combination returns a different result. However, it is not possible to prove that such a input sequence does not exist (any input sequence might produce a different result if prepended by another invocation).
(Even if you check the values of fields found via reflection, those might change without influencing the lambda's result, therefore not really making it stateful).
Here's a short compilable example showing both false positive and negatives, disproving the notion:
public class StatefulLambda {
static AtomicInteger counter = new AtomicInteger();
public static void main(String[] args) {
// false negative: will return different result each call
System.out.println(hasState(i -> counter.incrementAndGet()));
// false positive: will always return the same result
Object object = new Object() {
final int i = 0;
};
System.out.println(hasState(i -> object.toString()));
}
private static boolean hasState(Function<?,?> lambda) {
return lambda.getClass().getDeclaredFields().length > 0;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With