-
Notifications
You must be signed in to change notification settings - Fork 1
Description
There's a recurring need for more control over how we compare and/or merge signatures.
These often involve some logic on parameter objects (with their name, kind, and optionally default and annotation), order, etc.
We'd like to have a clean framework that enables the user to easily and correctly define these functions, reusing much of the common logic.
Examples:
- comparison Boolean operators/functions such as:
sig1 == sig2: equality (more precisely "equivalence relation") of two signaturessig1 <= sig2: comparison (more precisely "total order relation" asissubset,issubclassetc.)
- operators/functions such as signature merging (
sig1 + sig2) - function that gives a score or more complex information about how appropriate it is to feed the function with signature
sig1to an input value of function with signaturesig2
Don't miss this comment that proposes a design.
Notes
Return type of a comparison
Must cases might just need a Boolean, like with x == y or x <= y (or issubset, issubclass, etc.).
But in some cases, such as with self-organizing code (or less crazily: validation scores), we'd like to have a numerical (or more generally, vectorial) score, or more generally, some "comparable" type that can be used to do things like "best match".
Use a key function or a binary comparison function as the specifier?
Might want to express comparisons based on key functions like builtin sorted, max etc. do. What are the pros/cons? It seems like a cleaner design enabling easier UX (and obviously, a big pro is the interface-consistency with familiar builtins). But, for example, is it complete? Are there things we cannot do with key functions that we can with the usual binary operator way (specifying comparison function via a two-element boolean function such as compare(x, y)).
For example, how would comparison scores be derived from key functions? Even if it's possible to "fit" any comparison function with vectorial key functions, would it be the most intuitive way of expressing it?
References
Related issues
- Dag.ch_func and signature comparison
- Enable code_to_dag to use wrapped function signature for the dag signature it produces, which could be a convenient interface for the user to get over the restrictive signature comparison when using
code_to_dag. But that's only forcode_to_dag. Still, the long issue has some reflections about signature comparison. - The right way to parametrize comparison operators, though the subject is about using operators to compare signatures, also has some relevant ideas.
- Need a more powerful and clean signature merging functionality: Indeed, we encounter the signature comparison concern again when we do signature merging (union). There are useful pieces of code around the problem that one could collect to get a better idea of the problem.
- Write a general parameters merging function: an older signature merging issue, possibly duplicate.
- Revise, refactor and robust(ize) function normalization tools: Because signature comparison comes up in the situations described there.
- Rethink what i2.Sig instances should do, or not do also contains some analysis around the subject of signature comparison
- The "Binding changes when using ch_funcs" was perceived as a bug, but wasn't. The clarification points yet once more to the need of proper signature comparison (and error messages for them).
Further notes
The definition of signature equality
Sig doesn't redefine it -- the builtin is used, which boils down to using the following (acts basically as a "key function"):
def _hash_basis(self):
params = tuple(param for param in self.parameters.values()
if param.kind != _KEYWORD_ONLY)
kwo_params = {param.name: param for param in self.parameters.values()
if param.kind == _KEYWORD_ONLY}
return params, kwo_params, self.return_annotation