Rant after trying Rust a bit

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Mon Jul 27 14:49:15 PDT 2015


On Monday, 27 July 2015 at 19:21:10 UTC, Tobias Müller wrote:
> "Jonathan M Davis" <jmdavisProg at gmx.com> wrote:
>> On a related note, while I'd noticed it on some level, I don't 
>> think that it had ever clicked for me how restrictive 
>> interfaces are before this discussion. The simple fact that 
>> you can't ask for two of them at once really reduces how 
>> reusable your code can be. So, templatizing those checks 
>> rather than using interfaces is huge. And DbI is an extension 
>> of that. There's likely a lot of unplumbed depth there.
>
> One big improvement of traits over interfaces is, that you can 
> implement traits for types after they are defined, even for 
> types that you didn't define yourself.
>
> So in Rust, if your function needs two unrelated interfaces 
> (trait objects == dynamic polymorphism) A and B, you can easily 
> define a new trait C that depends on A and B and implement C 
> for all types that also implement A and B:
>
> trait A {...}
> trait B {...}
>
> trait C : A,B { }

How is that any different from interfaces? You can do exactly the 
same thing with them.

> impl<T: A+B> C for T { }
>
> fn myFunction(c: C) {...}
>
> For generics you don't even need that:
>
> fn myFunction<T: A+B>(t: T) {...}

As long as you can list the two interfaces/traits/concepts that 
you require separately, then you're okay. But as soon as you have 
to create a new one that combines two or more 
interfaces/traits/concepts, then that doesn't scale. interfaces 
force that. I wouldn't expect traits or concepts to, because 
they're compile-time constructs, but that would depend on how the 
language defines them.

It might make sense to create combined traits/concepts for the 
cases where the operations in question are often going to be 
required together, but in general, it's going to scale far better 
to require them separately rather than require a combined 
trait/concept. Otherwise, you get a combinatorial explosion of 
traits/concepts as you combine them to create new traits/concepts 
- either that, or you code doesn't end up being very generic, 
because it's frequently using traits/concepts that require more 
operations than it actually uses, meaning that it will work with 
fewer types than it would otherwise.

In general, templates shouldn't be requiring more operations than 
they actually use, or they won't be as reusable as they 
could/should be. And that implies that the list of required 
operations should be kept to what's actually required rather than 
using traits/concepts that require those operations plus others.

- Jonathan M Davis


More information about the Digitalmars-d mailing list