Open
Description
About
This effort is aimed at reducing complexity and tech debt relating to the so called "API-decorators". The purpose of the decorators is to:
- Ensure that type conversions and host-device transfers only happen when absolutely necessary.
- Allow users to provide array-like input data in the type of their choice and also return results in the same type.
We identified the following key problems with the current implementation:
- The inherent complexity makes it hard for developers to follow the control and data flow.
- The use of magically applied decorators
a. removes any obvious visual trigger to developers that they must be aware of the special behavior of a function,
b. reduce confidence in said behavior. - Non-obvious naming further obfuscates that developers must be aware of special behavior.
The revised implementation should
- Clearly communicate to developers what types to expect and what they must return and to prevent or at least discourage unnecessary conversions.
- Clearly communicate to users what types they can provide and what to expect in return (typically the same type).
The improved implementation is aiming to achieve three main things:
- Simplify the developer API
- Reduce implementation complexity
- Reduce magic behavior
Only loosely related to this, we should aim to actually use type-checking to check that decorators are correctly applied and the correct return types are returned.
Tasks
- Avoid need for DecoratorMetaClass
- Use factory functions instead of multiple-inheritance for Decorator class implementation.
- Use the same decorators for base-class methods and free-floating functions.
- Reduce number of decorator (aliases) in preference of configurable decorators and improve naming.
- Use a stack to keep track of the output type
- Do not automatically apply decorators; instead require that certain functions are always decorated for classes that derive from Base.
- Do not allow for multiple decorators to be applied, or have them replace the old one, but in any case do not silently ignore decorators when one was previously applied; like other magic this introduces uncertainty about whether a decorator is applied or not.
- Do not use type annotations to infer output types during runtime; instead use decorators that are type-checked; but check whether the decorator and the type annotation match.