Runtime dependency checking
Frustrated
Frustrated at nowhere.com
Tue Feb 25 16:28:23 PST 2014
http://dpaste.dzfl.pl/80c6225ed090
The code above demonstrates run-time contracts using interface
based programming.
It provides two co-benfits: Simplified class implementation(you
do not have to use interfaces for types which then requires
casting that type for orthogonal behavior) and run-time contracts.
e.g., The WindowsGui class is implemented using WindowsButton and
not iButton. This allows one to avoid having to cast the iButton
to a WindowsButton when one wants to use the featuers of a
WindowsButton.
A contract is created that every iButton used in WindowsGui must
be a WindowsButton or an error is thrown. This creates a run-time
contract or dependency between WindowsGui and WindowsButton.
Normally in such interface based programming the contract is not
automatic and any iButton(for example, a linux button) could be
used for the WindowsGui. Normally this is not desired behavior as
it limits what WindowsGui can do.
Basically when we "lift" a class to an interface and any objects
used in that class to interfaces we create contract that is in
general too generic(but easier to specify in the language). This
creates generally creates a problem for the implementations of
the interface by forcing them to be more generic than one wants.
To solve this requires casting and type checking to get the more
specific type. The mixin attempts to automate this. It would be
nice if the language was extended to allow covariance on argument
types, e.g.,
interface iGui
{
@property T button(T : iButton)(T button); // Syntax says
that any T can be used as long as it is derived from
iButton(instead of just an iButton)
}
class WindowsGui : iGui
{
@property WindowsButton button(WindowsButton button) { }
// implements the iGui.button property since it satisfies the
contract and also allows us to use the type we actually want to
use. (no explicit casts or checks)
}
Now, WindowsGui.button might be used with an iButton, so an
implicit check is required to make sure that iButton is of
WindowsButton type.
The compiler could handle this quite easily. The mixin emulates
such a feature. The mixin is not robust though.
I seriously doubt that we'll ever get the semantics to handle
this though.
In any case, I think there is real benefit here and it makes it
easier to do modular programming in D with proper dependency
checking(WindowsGui is dependent on WindowsButton, not iButton or
LinuxButton and this dependency is retained even when we use the
iGui and iButton interface).
Now, in the meantime I'll work on tidying up the mixin code but I
was thinking about adding versioning. I could have a version
property in all the types only if the versions have the same
major version are they compatible. So a WindowsGui 3.42 is not
compatible with a WindowsButton 2.89. Not sure if this a good way
or if it will cause headaches later on. (I could keep a file of
all the version compatibilities but that seems excessive)
Any ideas?
---- output ----
Trying WindowsButton with WindowsGui!
Do(): WindowsButton
WindowsButton.foo(): I'm an extra WindowsButton feature!
...WindowsButton works in WindowsGui!
Trying WindowsBorder with WindowsGui!
Do(): WindowsBorder
WindowsBorder.foo(): I'm an extra WindowsBorder feature!
...WindowsBorder works in WindowsGui!
Trying LinuxBorder with WindowsGui!
Invalid object type dependency mismatch! Type: f872.LinuxBorder
Type Expected: WindowsBorder
Trying LinuxButton with WindowsGui!
Invalid object type dependency mismatch! Type: f872.LinuxButton
Type Expected: WindowsButton
Trying WindowsButton with LinuxGui!
Invalid object type dependency mismatch! Type: f872.WindowsButton
Type Expected: LinuxButton
Trying LinuxButton with LinuxGui!
Do(): LinuxButton
...LinuxButton works in LinuxGui!
Trying WindowsBorder with LinuxGui!
Invalid object type dependency mismatch! Type: f872.WindowsBorder
Type Expected: LinuxBorder
Trying LinuxBorder with LinuxGui!
Do(): LinuxBorder
...LinuxBorder works in LinuxGui!
More information about the Digitalmars-d-learn
mailing list