July 23, 2015
On Thursday, 23 July 2015 at 15:20:36 UTC, jmh530 wrote:
> It definitely seems weird that this behavior isn't
> mentioned anywhere.

It isn't really expanded upon, but the : Interfaces at the top here tells you can inherit them:

http://dlang.org/interface.html

It doesn't show an example in the text of an interface extending another interface, but it does say "interfaces can be inherited".

> Also, the use of static* or final methods in the interface can allow default implementations of methods.

Eh sort of but not really. static and final methods cannot be overridden in the virtual sense.

interface Foo {
        final void foo() { writeln("foo"); }
}
class Bar : Foo {
        override void foo() { writeln("foo from bar"); }
}


b.d(8): Error: function b.Bar.foo does not override any function, did you mean
o override 'b.Foo.foo'?
b.d(8): Error: function b.Bar.foo cannot override final function Foo.b.Foo.foo



Static is similar, change those finals to static and you get:


b.d(8): Error: function b.Bar.foo cannot override a non-virtual function


Take override off and it compiles... but is statically dispatched:

        Foo bar = new Bar();
        bar.foo(); // calls the version from the interface

        Bar bar = new Bar();
        bar.foo(); // calls the version from the class



That's the main thing with interfaces: you are supposed to get the overridden method when you call it through the base, but that only happens if it is virtual - neither final nor static. And those cannot have default implementations in a D interface, only in a class.

> The tricky part is that I had been using something like final foo() { } instead of final void foo() { }. For some reason you can override the first, but not the second.


You just defined a template by skipping the return type... templates are allowed in D interfaces and classes, but are always implicitly final, and thus get the behavior above - if you call it through the interface, you get a different func than calling it through the class.




BTW you can also check interface conversion for objects in a template function and get static dispatch that way... sort of:

void something(T : Foo)(T bar) {
        bar.foo();
}
void main() {
        Foo bar = new Bar();  // explicitly using the interface
        something(bar); // leads to this calling "foo"

        // but if you did "auto bar = new Bar();" or "Bar bar"
       // it would call "foo from bar"
}
July 23, 2015
On Thursday, 23 July 2015 at 14:49:55 UTC, ixid wrote:
> On Thursday, 23 July 2015 at 13:33:43 UTC, Adam D. Ruppe wrote:
>> On Wednesday, 22 July 2015 at 21:04:57 UTC, simendsjo wrote:
>>> :) The example was written to save space. I recon you understand what I mean.
>>
>> Yeah, but the if/else is one of the most useful examples of it, and is covered by ?:, so the whole thing becomes less compelling then.
>>
>> The other places where I've used it in languages that support it are little blocks crammed into a line and sometimes exception grabbing... but still, the value isn't that great.
>
> If we had a clean sheet wouldn't it be better to have if return a value and ditch ternary?

Maybe, but the ternary operator is a lot less verbose, and from some other comments in this thread, it sounds like the way they implemented it in Rust forces you to use braces for single line statements, which would be a _huge_ downside IMHO. I'm inclined to think that it would need a use case that's a lot more compelling than if-else chains to be worth it.

- Jonathan M Davis
July 23, 2015
On Thursday, 23 July 2015 at 15:37:24 UTC, shannon mackey wrote:
> "> On Wednesday, 22 July 2015 at 19:41:16 UTC, Jack Stouffer wrote:
> On Wednesday, 22 July 2015 at 20:43:04 UTC, simendsjo wrote:
>>> On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote:
>>>> [...]
>>>
>>> Don't quite know what you mean here.
>>
>> When "everything" is an expressions, you can write things like
>>     auto a = if(e) c else d;
>>
>> In D you have to write
>>     type a = invalid_value;
>>     if(e) a = c;
>>     else  a = d;
>>     assert(a != invalid_value);
>>"
>
> I frequently do things like this in D:
>
>         auto good = ( true == true ) ? "true" : "false";
>
> which looks a lot like your Rust example?  Is that not what you were looking for?

Sorry, I didn't read to the end of the thread, and this has been covered many times.
July 23, 2015
On Wednesday, 22 July 2015 at 20:43:04 UTC, simendsjo wrote:

> Let me add a point for Rust somewhat related :)
>
> Community
> ---------
> The community is nice, helpful and doesn't condecent people.

I'd challenge you to write something other than 100% praise for Rust and see how nice the community is. Not that their community is bad, but they won't be winning any awards. Disclaimer: I gave up on Rust quite a while ago.


> I disagree. String mixins are much easier to abuse than hygenic
> macros. String mixins allows anything, and while it offers
> infinite possibilities, it also encourage abuse.

As someone that used to spend a lot of time with Lisp, I find it funny that macros are promoted as a way to avoid abuse of language features. On the issue of hygienic macros, there's a reason the major Scheme implementations still offer Common Lisp-style macros, in spite of the obvious theoretical advantages.
July 23, 2015
On Wednesday, 22 July 2015 at 19:54:05 UTC, Dicebot wrote:
>
> D has done many things wrong, but there is one right thing that totally outshines it all - it is cost-effective and pragmatical tool for a very wide scope of applications.

+1, from a business D user!
---
Paolo


July 23, 2015
On Thursday, 23 July 2015 at 13:33:48 UTC, Andrei Alexandrescu wrote:
> On 7/22/15 7:47 PM, rsw0x wrote:
>> On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote:
>>> ...
>>
>> I think rust makes the ugliness of D's "push everything into phobos for
>> simplicity" become very visible. D and Rust share many equal constructs,
>> but D's is almost always uglier.
>
> Care for a list? Thanks! -- Andrei

Ugliness is in the eyes of the beholder, for me for example is kinda funny when people call D syntax better than Rust, for me those are nearly the same (I do know lisp).

Back to topic:
Rust's compiler is aware of some traits and attributes:
http://doc.rust-lang.org/std/clone/trait.Clone.html which disables move semantics
or other traits grouped here:
http://doc.rust-lang.org/std/marker/

This works sort of the way D compiler is aware of input ranges or druntime for foreach and makes it possible to create alternative standard libraries like https://github.com/carllerche/mio

D has equivalent capabilities in most cases, but it's way less consistent in a way they're provided.

As an example: D has __traits + isExpressions + template constraints phobos wrappers where Rust has trait: http://doc.rust-lang.org/std/marker/trait.Reflect.html + template constraints
D has some rules which types have size at compile time, Rust has http://doc.rust-lang.org/std/marker/trait.Sized.html
D has rules for sharing certain types, Rust has http://doc.rust-lang.org/std/marker/trait.Sync.html
D has operator overloading while Rust has that to, but using traits: http://rustbyexample.com/trait/ops.html
D has special druntime Object type, Rust has a hash trait, cmp trait http://doc.rust-lang.org/core/cmp/index.html http://doc.rust-lang.org/core/hash/index.html which are more elastic.

This is in no way deal breaker because things are there in D. On the other hand learning is much easier because things are consistent. First example did hurt me badly, juggling 6 docs files for type introspection. That's what I think simendsjo meant about "ugliness".

I think the reason for this "mess" in D is that D is developed in a very ad hoc way, while for rust things really get peer reviewed and tested for a long period of time.
July 23, 2015
On 7/23/15 10:49 AM, ixid wrote:
> On Thursday, 23 July 2015 at 13:33:43 UTC, Adam D. Ruppe wrote:
>> On Wednesday, 22 July 2015 at 21:04:57 UTC, simendsjo wrote:
>>> :) The example was written to save space. I recon you understand what
>>> I mean.
>>
>> Yeah, but the if/else is one of the most useful examples of it, and is
>> covered by ?:, so the whole thing becomes less compelling then.
>>
>> The other places where I've used it in languages that support it are
>> little blocks crammed into a line and sometimes exception grabbing...
>> but still, the value isn't that great.
>
> If we had a clean sheet wouldn't it be better to have if return a value
> and ditch ternary?

Possibly, but then you'd need to have while return a value. -- Andrei
July 23, 2015
Dicebot:
 D has done many things wrong, but there is one right thing that
> totally outshines it all - it is cost-effective and pragmatical tool for a very wide scope of applications.

would you care to write more on this as a blog post, making it vivid and setting out some examples?  that's my tentative judgement too, and why I am here, but I lean very heavily on my intuition and that's not enough to persuade other people when I don't yet have mastery of the relevant domain knowledge, having returned to programming quite recently.  I am talking to another decent-sized hf that might be open to exploring the use of D, but the more vivid people are able to make the case the better.



July 23, 2015
On Thursday, 23 July 2015 at 15:38:53 UTC, Adam D. Ruppe wrote:
>
> It isn't really expanded upon, but the : Interfaces at the top here tells you can inherit them:
>
> http://dlang.org/interface.html
>
> It doesn't show an example in the text of an interface extending another interface, but it does say "interfaces can be inherited".
>

I see that now. It's there, but it's practically a throw-a-way line. I've looked at that page a bunch of times and skipped over it each time. This is a broader problem with D's reference pages.

Compare
http://dlang.org/interface.html
with
https://doc.rust-lang.org/book/traits.html
which is better?

Rust's documentation uses clear examples to show how something should be used and the most important features. By contrast, there are many parts of D's documentation that someone with less-than-expert programming knowledge will find quite difficult to understand.

For instance, look at
http://dlang.org/function.html
you have to scroll down for quite a while before you even get to anything useful. Then, what's the first thing that comes up? Something about contracts, return values, bodies, purity. Not "this is what a D function is".

I'm all for a complete reference of every D feature, but there needs to be some step up in terms of difficulty of the material. Start with the basics, then work up into all the specifics. I'd say at a minimum some of this documentation needs to be broken up into several pages.

There seem to be a lot of places where I could improve the D documentation. However, I feel like if I start going crazy with changes I might get some push-back...

>
> BTW you can also check interface conversion for objects in a template function and get static dispatch that way... sort of:
>
> void something(T : Foo)(T bar) {
>         bar.foo();
> }
> void main() {
>         Foo bar = new Bar();  // explicitly using the interface
>         something(bar); // leads to this calling "foo"
>
>         // but if you did "auto bar = new Bar();" or "Bar bar"
>        // it would call "foo from bar"
> }

This is cool and I wasn't aware that you could do this. I was trying to use std.traits' InterfacesTuple to test that a class had a particular interface.

However, I also find it a bit confusing. I don't understand precisely what it means when the interface is on the left. It's like you're using the class to create an object of a type the same as the interface...Nevertheless, the interface page says you can't do this
D d = new D();
where D is an interface. However, it also says that you can
D d = cast(D) b;
where b is some an object of some other class B that inherits the interface D. You example does not fit either of these cases. Then, if you change Foo to not be final and Bar to not override and run it, it will call "foo from bar" regardless of whether you do
Foo bar = new Bar();
or
Bar bar = new Bar();
July 23, 2015
On Thursday, 23 July 2015 at 16:22:30 UTC, QAston wrote:
(... snip ...)
> That's what I think simendsjo meant about "ugliness".

Someone else wrote about the "ugliness", not me.