www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Bolts 1.4 - added experimental signatures for D

reply aliak <something something.com> writes:
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
Feb 14 2020
parent aliak <something something.com> writes:
On Friday, 14 February 2020 at 21:33:01 UTC, aliak wrote:
 Hi,
 [...]

 Cheers,
 - ali
Ok, you can now model an actual input range with most of it's caveats: interface InputRange(T) { property bool empty(); property T front(); ignoreAttributes void popFront(); } struct MyRange { mixin Models!(InputRange!int); } source/bolts/experimental/signatures.d(341,5): Error: static assert: "Type MyRange does not comply to signature InputRange!(int) Missing identifier empty of type bool. Missing identifier front of type int. Missing identifier popFront of function type void(). source/bolts/experimental/signatures.d(8): <-- Signature InputRange!(int) defined here. source/bolts/experimental/signatures.d(15): <-- Checked here." To fix the errors you'd need a name called empty that returns a bool (i.e. is a member variable or a property function). Same with front. And for popFront it can be a function with whichever attributes attached to it. Not sure what to do with a range model that has "ref T front". Maybe an ignoreRefness attribute? Cheers
Feb 19 2020