-
Notifications
You must be signed in to change notification settings - Fork 4
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
Multiple arguments #14
Comments
Yeah, you would need to define an interface that is specifically for e.g. type a working where type b is the second argument to function f. It would be cool if you could specify the traits allowed for b. |
At the moment I don't care about traits, but I would like to specify an interface like the following (let's ignore the liberties I took with Interfaces.jl syntax): @interface AbstractGraph{V} (
mandatory = (
vertices(::AbstractGraph),
edges(::AbstractGraph),
neighbors(:::AbstractGraph{V}, ::V)
),
) |
We just need to write the macro code to detect that I guess. But do you only want to know that the methods exist? Or actually compile/run something? If the second argument accepts In the end its hard to beat just using an anonymous function and running the thing. |
If the goal is to have compile-time checking, we are not allowed to run anything, right? |
The goal is not compile-time checking, thats a pretty limited check of an interface working. E.g. it cant catch half of the OffsetArrays.jl bugs and most other correctness bugs that got me thinking about this in the first place. While the traits are compile time, the check can go in precompile or tests. So the fact that the check actually runs is socially enforced rather than compiler enforced. Not perfect of course. |
The trouble is, for some of these functions there is no "default value" to run them on. Typically, the graphs interface requires access functions but no specific constructors |
You need to provide test objects to run the interface tests. Or do you mean for the second argument? You could create that from Just make the test objects for additional arguments in the function is the idea. Maybe we can look at how to do this combinatorially, idk. |
Riiight, so |
So what needs to change is the syntax for interface declaration and testing. |
As for the macro, my first example might be a little hard to achieve in terms of parsing, but this simplified version would already go a long way: @interface AbstractGraphInterface (
mandatory = (
vertices(g::AbstractGraph),
edges(g::AbstractGraph),
neighbors(g:::AbstractGraph, v)
),
) Note the difference between the interface name and the type name, cause this is an inheritance-free interface unlike RequiredInterfaces.jl. Then we could pass something like Dict(g => MyConcreteGraph(), v => 1) to the tests? |
Can we separate out the nice syntax idea and multiple arguments idea? Ultimately the macro needs to generate some anonymous function anyway. (A macro-free MWE forces us to address how this will actually work - the current macro just copies the code unchanged, there is no magic) |
I'm confused, to me the new syntax is necessary to accept multiple arguments of different types |
The output of the Those functions get run in the tests for each trait. So working out the syntax of the final functions is the important part... then we can look at how to map that to a DSL like your example, if its actually necessary. (Look at the readme examples. They are barely modified by the macro, thats the actual structure thats used in the tests. How do they need to change if we have multiple arguments is the question) |
I'm sorry I still don't understand what kind of "macro-free example" you want. @interface AbstractGraphInterface (
mandatory = (
has_vertex = (g, u) -> has_vertex(g, u) isa Bool,
has_edge = (g, u, v) -> has_edge(g, u, v) isa Bool,
),
optional = (;)
) The main question I have is how to impose the type of |
Thanks thats what I meant. If the object is an array or similar we can use I guess there are cases where things like that are not possible and we need a way to pass in the extra arguments to the tests on a trait-by-trait basis (and those will be passed to the anonymous function). Isnt imposing types on g just (Types are not specified by default because a lot of interfaces are trait based, so an object being a certain type is just a check you write like any other. We can add syntax for that if it makes things clearer, but its very little code to just write it out as the first condition) |
That's rather specific, and in our case it wouldn't work cause we want to apply this to arbitrary graphs created by the user, with arbitrary vertex types. So letting the user give the arguments in the test seems like the only way out
In my mind, the interface is linked to a single type, like |
Well I did mention the general solution below that...
All
I dont understand now. The interface is applied to a type in the I guess we could add a type argument and have the default be The you could skip the |
Yes but where is the @interface AbstractGraphInterface SomeType (
mandatory = (
has_vertex = (g::SomeType, u) -> has_vertex(g, u) isa Bool,
has_edge = (g::SomeType, u, v) -> has_edge(g, u, v) isa Bool,
),
optional = (;)
) But in that case the anonymous functions cannot work until the user gives their actual |
Im so confused... the person that implements the istherighttype = g -> g isa SomeType We can of course add this to the macro as magic, but lets stick to functions here. Or... are you trying to say you want a check that there are functions defined for exactly some specific type rather than a generic falback? Otherwise Im lost here I dont get why you need this: g::SomeType If right above it you have g -> g isa SomeType These functions in mandatory just run in sequence, so Like: mandatory = (
istherighttype = g -> g isa SomeType,
has_vertex = (g, u) -> has_vertex(g, u) isa Bool,
has_edge = (g, u, v) -> has_edge(g, u, v) isa Bool,
), I guess we are not clear on how the objects are passed to the tests now there are multiple arguments... I was assuming only the extra args are passed in where needed, and g is always just the same object. |
I think it might be a good idea to have a 15-min zoom call one of these days, if you're open to it 😅 this is getting a bit tedious |
Its basically always like this lol... the difficulty of these discussions is a lot of why I stopped working on this package, I never experienced anything like it. Peoples idea of what an interface declaration is/should be is just wildly different. But Im actually mostly free today, central european time zone. |
Roadmap
|
How do we include methods in the interface that take several arguments of different types?
The text was updated successfully, but these errors were encountered: