tk3369 / BinaryTraits.jl

Can do or not? It's easy. See https://tk3369.github.io/BinaryTraits.jl/dev/
MIT License
53 stars 3 forks source link

Mandated return value for a contract #46

Open tk3369 opened 4 years ago

tk3369 commented 4 years ago

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:

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 return Is{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 return true".

For that reason, we can design syntax such that a contract must return a true value.

JeffreySarnoff commented 4 years ago

Is this either [a] conflating contract and contracts, or [b] admixing interface recognition and interface specification?

tk3369 commented 4 years ago

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}().