Open tk3369 opened 4 years ago
Is this either [a] conflating contract and contracts, or [b] admixing interface recognition and interface specification?
Sorry, I don't quite understand what you mean. Let me explain a little further about this hypothetical situation:
From the framework provider perspective:
Please implement function istable(x::T) = true
so that I know you have also extended my functions column_names(x::T, args)
and num_rows(x::T, args)
with your own implementation. Implementing istable
is the only requirement to participate in my framework but you must ensure that all required functions are implemented. Take a look at my documentation, dude! BTW, I have no intention to adopt BinaryTraits.
From the implementer perspective: I love your framework, and I will implement whatever you ask me to do. I hate reading documentation though. Is there a place there it just tells me exactly what I need to implement? Is there a tool that I can verify that my implementation is correct?
BinaryTraits people: Hey, come take a look at BinaryTraitsRegistry.jl. We have formalize the interface with the following specification:
@trait Table
@implement Is{Table} by istable(T) => true # made-up syntax
@implement Is{Table} by column_names(_)
@implement Is{Table} by num_rows(_)
Now, implementer comes back: Alright, now I know exactly what to do. Let me try the following:
struct AwesomeTable end
istable(::Type{AwesomeTable}) = true
column_names(x::AwesomeTable) = []
num_rows(x::AwesomeTable) = 0
@check AwesomeTable
It would be nicer, however, if both framework provider and implementer use the same trait system. The istable
contract is not entirely necessary because we already know trait(Table,AwesomeTable)
returns Is{Table}()
.
Some interfaces requires the implementer to define a function that returns
true
so that it knows if a type has implemented the interface at runtime.Examples:
Tables.istable
IteratorInterfaceExtensions.isiterable
Technically, this is not necessary anymore if these packages adopt BinaryTraits because they can just call the trait function e.g.
trait(Table,x)
and it would returnIs{Table}()
for a properly implemented type.I do not expect, however, that everyone will adopt BinaryTraits. Yet, an implementer may still want to use BinaryTraits' function to verify correct implementation of the interface. It can be achieved if we have a "BinaryTraitsLibrary" that defines a bunch of well-known traits and the respective interface contracts. Now, one of the contracts for Tables.jl will be "hey, you must extend my
istable
function and returntrue
".For that reason, we can design syntax such that a contract must return a
true
value.