4 days ago
Hi,

I've released an experimental implementation of the concept of traits/signatures/protocols-ish. The basics seems to work decently well, with very decent error messages e.g.:

source/bolts/experimental/signature.d(111,17): Error: static assert:  "Type Y is missing the following members of enum X: ["three"]
  source/bolts/experimental/signature.d(156): <-- Signature Sig defined here.
  source/bolts/experimental/signature.d(166): <-- Mixed in here."

Package: https://code.dlang.org/packages/bolts
Implementation PR: https://github.com/aliak00/bolts/pull/6/files

I'm not sure about a few things thought and wouldn't mind some feedback.

1. Malleable properties. Take input ranges for example:

struct InputRange(T) {
  bool empty() { return true; }
  // other members...
}

This works:

struct SomeRange(T) {
  mixin ModelsSignature!(InputRange!T));
  bool empty() { return true; }
  // other members...
}

But for variations such as infinite ranges, this will not work

struct SomeRange(T) {
  mixin ModelsSignature!(InputRange!T));
  enum empty = false;
  // other members...
}

The way I'm thinking of handling it right now is by using UDAs?

struct InputRange(T) {
  @onlyAssign
  bool empty;
  // other members...
}

So then the mixin template Models will check if a name has the UDA onlyAssign attached to it, and if so it will be more lenient with the SomeRange struct.

Does anyone have any other suggestions?

2. Naming. Not very happy with onlyAssign, and also ModelsSignature. Any bikesheds? :p

3. Having to implement functions. Like in the InputRange signature above, I had to implement function empty. So for that I'm thinking templates? Something like:

struct Signature {
  mixin Function!("f", int(int, int));
}

Or the like? And the mixin would put in a stubbed function named "f" that returns int.init

Opinions?

Cheers,
- ali