Improve usability of op built-in methods
- Dominant language
- Java
- Stars
- 94
- Forks
- 44
- PR merge metrics
- No merged PRs in 30d
Description
We actually have four scenarios:
1. Run an op type-safely.
2. Run an op type-flexibly.
3. Match an op type-safely.
4. Match an op type-flexibly.
Right now, the built-in method signatures cover case (1) above. And the `OpService`'s `op` method covers (4). We also partially/limitedly cover (3) and (4) via the `Functions`, `Computers`, `Inplaces` and `Hybrids` utility class methods.
I want to improve the API and/or architecture to make all four scenarios above easy.
-----
What follows are some now-stale notes I wrote while thinking about this problem. I have other thoughts too, but no time to write them down at this moment. Please note that the ideas below do not necessarily represent current thinking—I just want to keep them preserved somewhere so they are not totally lost. I will return to this issue as I stumble across other ideas, topic branches, etc. The gist of this issue is simply to fulfill the requirements outlined above.. somehow!
* Split built-in type-safe methods out of `OpEnvironment`. This is long overdue; the `OpEnvironment` should not be compile-time entangled with the entire core ops library.
* `TOps` object has a `TOpEnvironment` referencing typed `Namespace` objects and typed method signatures.
* Should this be generated at compile time? Or at runtime? Probably want to generate at compile time, so that code completion works in IDEs.
* `UOps` object has a `UOpEnvironment` referencing untyped namespaces and `Object...` method signatures.
* Should this be generated at compile time? Or at runtime? Probably want to generate at runtime, so that scripts are 100% extensible.
-----
```groovy
//
// 1. Run an op type-safely.
// Need to ensure there are aliases for all op namespaces.
//
// @CreateKernelNamespace kernel
k = kernel.gauss(...typed...)
// -- LONGER --
// @CreateNamespace create
k = create.kernel().gauss(...typed...)
// -- LONGEST --
// @OpService ops
k = ops().create().kernel().gauss(...typed...)
```
-----
```groovy
//
// 2. Run an op type-flexibly.
// A new interface hierarchy?
//
// @Ops.Create.Kernel kernel
k = kernel.gauss(...any...)
// -- LONGER --
// @Ops.Create create
k = create.kernel().gauss(...any...)
// -- LONGEST --
// @OpService ops
k = ops.create().kernel().gauss(...any...)
```
-----
```groovy
//
// 3. Match an op type-safely.
// A new interface hierarchy?
//
// @Ops ops
// @Ops.Create create
// @Ops.Create.Kernel kernel
op = kernel.gaussOp(...any...)
// also OK, but longer:
op = create.kernel().gaussOp(...any...)
// and longer still:
op = ops.create().kernel().gaussOp(...any...)
```
-----
```groovy
//
// 4. Match an op type-flexibly.
//
k = gauss.run(...any...)
// also OK, but longer:
k = kernel.gauss.run(...typed...)
// and longer still:
```
-----
Idea from @gab1one:
```python
# @OpService ops
# @OpGetService opgs
# @OpRunService oprs
img = ops.create().img(300,300)
add = opgs.math().add(int, int)
out = oprs.map(add, img)
out = ops.map().map(add, img)
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the existing OpEnvironment, OpService, Functions, Computers, Inplaces, and Hybrids APIs mentioned in the issue. Compare how they currently support the four type-safe and type-flexible run and match scenarios. The issue is complete only when the API or architecture makes all four scenarios easy, but it does not define a specific design or tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, developer-experience
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100