Interfaces.jl
Interfaces.jl copied to clipboard
Elaborate on goals
I think it would be an idea to elaborate a bit on the goals of this package - and hence on the goals of defining and implementing interfaces in Julia. (as this package has claimed a rather generic name - and is making good use of it 👍)
I.e. to compile a more elaborate list of goals and get these in the README/documentation.
To compile answers for issues brought up e.g. in
- https://github.com/JuliaLang/julia/issues/6975
- https://invenia.github.io/blog/2020/11/06/interfacetesting/
- https://viralinstruction.com/posts/badjulia/#abstract_interfaces_are_unenforced_and_undiscoverable
- https://discourse.julialang.org/t/towards-the-creation-of-an-interface-testing-package/82182
E.g., the obvious one:
- An interface should define which methods to implement.
But perhaps it's better to keep (suggested) goals in separate comments, so they can be easily voted for.
- Defining and implementing interfaces should be adoptable by the ecosystem, so the method should be compatible with the current direction of the community: A. Using traits to define interfaces informally. B. Reducing TTFX. C. Enabling static analysis. D. Enabling static compilation.
As mentioned in https://github.com/rafaqz/Interfaces.jl/issues/11#issuecomment-1568515893
- (supporting 2) The cost of both defining an interface and stating that an interface is implemented should be purely compile time and not a lot of it (close to zero).
These are great, thanks.
We can probably finish them up in a readme PR where anyone can suggest edits and additional points?
We can probably finish them up in a readme PR where anyone can suggest edits and additional points?
Yes 👍
- There should be (semi)automated testing to prove that an interface is implemented for a specific type, strongly coupled to the interface definition.
- An interface should provide low/no overhead traits so that it can be checked if it is implemented for a type
- An interface may also specify which types to inherit from (Maybe this should be 2)
- An interface may specify the types (and values??) a method must accept and return
4. There should be (semi)automated testing to prove that an interface is implemented for a specific type, strongly coupled to the interface definition.
Can you elaborate on "(semi)automated" (and testing) and "strongly coupled"?
I guess this means something like:
- The interface definition should provide enough information, that it enables the Interfaces package to provide a test method (
Interfaces.test), that makes it easy for users to implement tests of their interface implementations? (this is probably too specific for a goal) - The interface definition should provide enough information, that it enables compile-time enforcement/testing?
- The interface definition should enable test suites as described in https://invenia.github.io/blog/2020/11/06/interfacetesting/
Or maybe a rephrase of what is currently in the README?
- Defining an interface should enable tests.
- Or the long form: Defining an interface and stating that the interface is implemented for a type should enable testing that the latter is the case - by exploiting the information in the interface definition.
Sorry - this got unnecessarily long for a "please elaborate" comment :-)
5. An interface should provide low/no overhead traits so that it can be checked if an interface is implemented for a type
Can you elaborate on the concern here?
This is implementation that supports 4? And 2 (the community using traits already?)
6. (Maybe this should be 2)
We can always reorder in the PR, but also good to suggest ordering.
6. An interface may also specify which types to inherit from.
I.e. the goal is to support hierarchies of interfaces (as mentioned in #6)?
E.g. to support:
@interface AnimalInterface ...
@interface BirdInterface <: AnimalInterface ...
@implements BirdInterface Duck
and thus inheriting AnimalInterface in BirdInterface - and stating that both AnimalInterface and BirdInterface is implemented wrt. Duck.
- Interface definition - and interface implementation statement - should support multiple dispatch.
I.e., methods dispatch wrt. multiple arguments, so the interface definitions should support defining methods wrt. tuples of types.
(edit: @rafaqz you mentioned something like that in https://github.com/rafaqz/Interfaces.jl/issues/6#issuecomment-1185393722 - but that comment might be about something else...)
- I guess its hard to be more specific because there are various ideas floating around, and annoying constraints on optimal designs.
I was trying to capture that the interface definition contains tests. The strong coupling is via being in the same macro so the structure is forced. Previously the @implements macro actually put all the tests in a precompile function and ran it, so there was no ambiguity at all about the interface being tested - it was "automated" testing.
Now what we have is semi-automated, in that you get a function defined that runs tests, but you have to manually run it somewhere in your test suite and we have to trust that everyone does that. This is a compromise for performance, and it may not be possible to do more than this generally.
The interface definition should provide enough information, that it enables the Interfaces package to provide a test method (Interfaces.test), that makes it easy for users to implement tests of their interface implementations? (this is probably too specific for a goal)
This might be the most accurate goal though
The interface definition should provide enough information, that it enables compile-time enforcement/testing?
I don't think the compile time testing part is broadly possible in practice
The interface definition should enable test suites as described in https://invenia.github.io/blog/2020/11/06/interfacetesting/
The invenia blog style is the basis of a lot of this. But it hasn't lead to a consistent recognizable way of reading and running interface tests across the ecosystem. So we are aiming for a little more structure than that.
Or maybe a rephrase of what is currently in the README?
Defining an interface should enable tests.
As mentioned above it used to, but currently it does not automatically enable them, and its an open question if it should. (hmm maybe you meant "provide" here rather than "enable")
Or the long form: Defining an interface and stating that the interface is implemented for a type should enable testing that the latter is the case - by exploiting the information in the interface definition.
As a generic statement this one is pretty good :)
7. An interface may specify the types (and values??) a method must accept and return
I would suggest to leave the "values" part out of this to make it less controversial :-) Maybe put the "interface provides values" in a list of candidate goals being considered.
hah sorry I should have broken that up
hah sorry I should have broken that up
Feel free to edit (for the time being) :-)
5 This was to make it clear that traits and tests are not the same thing, and probably need to stay decoupled. So its really in opposition to 4. I have just found this to be a common point of confusion.
- This was simply saying that interfaces are not just about defining methods, and point 1 is incomplete. You can define all the methods in the AbstractArray interface of your own type, but it only follows the interface by also being
<: AbstracatArray.
- This was to make it clear that traits and tests are not the same thing, and probably need to stay decoupled. So its really in opposition to 4. I have just found this to be a common point of confusion.
Yes - good to get things clarified! 🙏 👍
So this was a response to 5 (not 6)? I.e.
- An interface should provide low/no overhead traits so that it can be checked if an interface is implemented for a type
Can you elaborate on the concern here?
This is implementation that supports 4? And 2 (the community using traits already?)
yeah, 5 :sweat_smile: