Split FunctionValue out of Applicable #843
Merged
+285
−286
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a refactoring-only change, and therefore very low-priority. But, it fixes a longstanding and (to me) irritating lack of type safety surrounding functions and operators.
The
Applicable
interface is widely used, but it is "confused" because functions and operators both implement it, even though those entities have very different capabilities and cannot be interchanged in TLA+.This commit adds a new
FunctionValue
interface so that TLC's code can distinguish between operators (OpValue
) and functions. Despite adding a new interface, the split actually REDUCES the number of non-comment lines of code in TLC.A few qualitative notes about why I think this is a good refactor:
Operator values have to implement
getDomain()
even though they do not have a domain. Therefore, knowing that a value isApplicable
is not enough to prove at compile-time that it supports everyApplicable
method.Similarly, all operator values have to implement
select()
, but all of them throw an exception.Code blocks that cast objects to
Applicable
are overly reliant on SANY's checks to ensure that the correct kind of value flows there.Operators and functions behave differently when called with more than 1 argument: operators can have arity > 1, but functions have to wrap the arguments in a tuple.
Note that
Applicable
has been retained because it is still widely used in the community modules. I hope that once the community modules switch to usingFunctionValue
andOpValue
correctly, we can completely removeApplicable
and the other now-deprecated methods.I have documented the key methods of
FunctionValue
andOpValue
as well as I can;Applicable
has no documentation I could find.