June 17, 2019
On Monday, 17 June 2019 at 12:11:19 UTC, lili wrote:

> Yes, It's ok. but this did not represent to an conception under code.
> I want to explicitly represent this is a SocketLike cenception.
> because i want conception oriented programming not type oriented, this is more powerful in GP.

It can still be done in D.  It's just the `std.traits` module is missing the `implements` trait I've naively implemented below:

```
import std.stdio;
import std.traits;

template implements(T, I)
{
    static foreach(m; __traits(allMembers, I))
    {
        static assert(
            is(typeof(__traits(getMember, T, m)) == typeof(__traits(getMember, I, m))),
            "`" ~ T.stringof ~ "` does not implement `" ~ I.stringof ~ "."
            ~__traits(identifier, __traits(getMember, I, m)) ~ "`");
    }
    enum implements = true;
}

interface ISocket
{
    int send(ubyte[] data, int len);
    int recv(ubyte[] buff, int len);
}

struct TcpSocket
{
    int send(ubyte[] data, int len) { writeln("TcpSocket send"); return len; }
    int recv(ubyte[] buff, int len) { writeln("TcpSocket recv"); return len; }
}

struct UdpSocket
{
    int send(ubyte[] data, int len) { writeln("UdpSocket send"); return len; }
    int recv(ubyte[] buff, int len) { writeln("UdpSocket recv"); return len; }
}

struct UnixSocket
{
    int send(ubyte[] data, int len) { writeln("UnixSocket send"); return len; }
    int recv(ubyte[] buff, int len) { writeln("UnixSocket recv"); return len; }
}

struct NotASocket { }

void Use(T)(T socket)
    if (implements!(T, ISocket)) // ensures `T : ISocket`
{
    socket.send([], 0);
    socket.recv([], 0);
}

void main()
{
    TcpSocket socket;
    socket.Use();

    NotASocket noSocket;
    noSocket.Use(); // Error: static assert:  "NotASocket does not implement ISocket.send"
}
```
https://run.dlang.io/is/KZcp1S

There's probably a much more professional and elegant way to write `implements`, but you get the idea.  It would probably be a worthwhile addition to the `std.traits` module for those that prefer it.

Mike
June 17, 2019
On Monday, 17 June 2019 at 10:25:57 UTC, lili wrote:
>
> Can't get your point. think what? C++ not support conception now.
> D not yet. But conception is really powerful. So is dlang will support it.
> for example: struct allow inherited interface, implement conception.

I think you mean C++ "concepts"[1]?. These do exist in D (since much earlier); they are called template constraints[2]:

	struct TcpSocket { /*...*/ }
	struct UdpSocket { /*...*/ }
	
	// Template constraint:
	template isSocket(T)
	{
		import std.traits;
		enum bool isSocket = /*...*/
	}
	
	auto UseSocket(ISocket)(ISocket sk)
		if(isSocket!ISocket)
	{ /*...*/ }

Still, template constraints or concepts work differently from Rust traits (or C# interfaces, which can be implemented by structs as well as classes). But they can be not so different ways to accomplish the same.

One difference is that D requires this "polymorphism" to be templated, while C# and Rust allow structs to implement interfaces/traits. (Probably there is no reason why D could or should not add this capability, at least as long as it does not turn structs from values to references when assigned to an interface value.)

This templated approach on the other hand is more flexible. Inheritance is not a sin as many people say nowadays, but it introduces rigidity in your design, and is not extensible for library users.
_______

[1] https://en.wikipedia.org/wiki/Concepts_(C%2B%2B)
[2] https://dlang.org/spec/template.html#template_constraints

June 17, 2019
On Monday, 17 June 2019 at 14:39:06 UTC, XavierAP wrote:
> On Monday, 17 June 2019 at 10:25:57 UTC, lili wrote:
>
> I think you mean C++ "concepts"[1]?. These do exist in D (since much earlier); they are called template constraints[2]:
>
> One difference is that D requires this "polymorphism" to be templated, while C# and Rust allow structs to implement interfaces/traits. (Probably there is no reason why D could or should not add this capability, at least as long as it does not turn structs from values to references when assigned to an interface value.)
>
> This templated approach on the other hand is more flexible. Inheritance is not a sin as many people say nowadays, but it introduces rigidity in your design, and is not extensible for library users.
> _______

Thanks your answer。 I just start learning dlang few days.


June 18, 2019
On Sunday, 16 June 2019 at 15:56:41 UTC, lili wrote:
> Hi, guys:
>    I really like Rust trait feature. Use it can implement duck-type simple.
>    base on inherited OO is complex and hard, because you need to design inherited tree well.
>    and this is not easy. In real word need runtime polymorphic is uncommon. lots of is just need compile time polymorphic.
>
> [...]

https://github.com/atilaneves/concepts
June 18, 2019
On 6/17/19 9:17 AM, Mike Franklin wrote:

> There's probably a much more professional and elegant way to write `implements`, but you get the idea.  It would probably be a worthwhile addition to the `std.traits` module for those that prefer it.
> 
> Mike

Ooh, that would be a nice addition to the standard library.

1 2
Next ›   Last »