Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hierarchy of interfaces #6

Open
Tokazama opened this issue Jul 14, 2022 · 10 comments · May be fixed by #43
Open

Hierarchy of interfaces #6

Tokazama opened this issue Jul 14, 2022 · 10 comments · May be fixed by #43

Comments

@Tokazama
Copy link

Do you have any suggestions on the best way to combine interfaces or make a hierarchy. For example, multidimensional indices could be thought of as a subset of the iteration interface. One might also want composite interfaces like those in BinaryTraits.jl

@rafaqz
Copy link
Owner

rafaqz commented Jul 14, 2022

Good question! I've been thinking about it but haven't settled on something yet.

We have abstract types already, so traits can work based on subtyping.

All the test components of a parent type can be accessed with a function of the type.

So we can pass the supertupe to the macro and add the required parent tests to the child types test function.

Syntax could be like:

@interface ChildInterface <: ParentInterface{(:setindex,)} (
   # Child tests here
)

This could give us an inheritance system for the optional components too?

You can also just do inheritance manually by splatting the parent types named tuple of tests into your own tests, but you lose the trait inheritance.

@Tokazama
Copy link
Author

I'm not sure the best syntax. I think the exact way you implement it will depend on what the end goal is here. If this is something that is supposed to be part of all interfaces at run time then it's going to take a lot of work and community buy-in. If it's something like Aqua.jl and every package could just have it as a test dependency, then we might not need to create a strict type hierarchy to support this.

@rafaqz
Copy link
Owner

rafaqz commented Jul 15, 2022

Well, its really a precompile time thing ;)

It may never be that widespread as a runtime dependency. But I think some package that does this needs to be, so its an attempt in that direction at the least.

Using it in tests isn't aiming so high, although people can use it for that too.

But implementing inheritance won't be hard. I will look at it in the next few days.

@Tokazama
Copy link
Author

The problem with the runtime aspect is that all we really want is a trait that gives a valid true or false on whether it prescribes to an interface. But we often want that to be known at compile time so a simple binary trait that assumes it is implemented correctly without testing that size, length, etc is actually returning integers or some other runtime dependent check. That's where I see something like this being really useful for tests. But I'm not the visionary here so I look forward to seeing what you come up with.

@rafaqz
Copy link
Owner

rafaqz commented Jul 15, 2022

Thats what we have!

The trait is just a compile time binary that the interface is implemented. But the macro forces the trait to be tested during precompilation, so the only way for it to be wrong is to manually define the trait functions, which I hope will be discouraged.

Edit: I implemented single dispatch inheritance, I'll push later when I have wifi. But I'm wondering if we want multiple inheritance instead, so you can combine interfaces.

@Tokazama
Copy link
Author

But testing that when loading the package is going to start adding a lot to compile time and initialize new methods in the method table, potentially causing invalidations in subsequent packages.

@rafaqz
Copy link
Owner

rafaqz commented Jul 15, 2022

Yes, probably it will be too slow.

The option is to define the interface structure at runtime and fill it out in InterfaceTests.jl. That will just take a little longer to write 😅.

It will just need a Interfaces.test(Interface, MyType) call in testing.

And probably the tests need to be defined separately to the runtime, which all gets a little more painful to organise.

This kind of thing really isn't julias strong point, and trying to do it makes that clear. But thats part of the excercise I guess: what is the most we can hope for.

@Tokazama
Copy link
Author

I'm not yet sold on this having a place in runtime code or package compilation, but I definitely can see the benefit of formally defining a set of tests that must pass for an interface to be correctly implemented. If that was the end goal it would be much easier to just build the interfaces with multiple levels and parents in a tree structure or list because performance wouldn't be critical.

@rafaqz
Copy link
Owner

rafaqz commented Jul 15, 2022

There should be an easy way to have tests and traits compiled separately but have them linked.

Just defing the interface list components at runtime has no overhead.

Then we can define and run the tests with method dispatch wherever we need to. A big interface can have a separate test package, a small one wouldn't need to worry.

@rafaqz
Copy link
Owner

rafaqz commented Jul 15, 2022

#8. Running tests in the test suite is enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants