Thread overview
interface function member declarations needing parameter attributes ?
Jul 17
someone
Jul 17
someone
Jul 17
someone
Jul 18
someone
Jul 18
someone
July 17
public interface intefaceWhatever {

   public bool doSomething(
      dstring lstrID,
      classX robjX
      );

}

vs

public interface intefaceWhatever {

   public bool doSomething(
      const dstring lstrID,
      ref classX robjX
      );

}

From the interface perspective: are these signatures identical or not ?

Is the latter needed ... or if not, makes sense as best practice ?

July 17

On Saturday, 17 July 2021 at 20:42:06 UTC, someone wrote:

>

From the interface perspective: are these signatures identical or not ?

No, they are very different.

But you also don't gain much from const here and that ref is probably actively harmful so i wouldn't use them here.

July 17

On Saturday, 17 July 2021 at 21:01:00 UTC, Adam Ruppe wrote:

>

No, they are very different.

So the lesson learned is that interfaces can also mandate member function's parameter attributes then ... right ?

>

But you also don't gain much from const here and that ref is probably actively harmful so i wouldn't use them here.

ref is gone.

July 17

On Saturday, 17 July 2021 at 22:43:15 UTC, someone wrote:

>

So the lesson learned is that interfaces can also mandate member function's parameter attributes then ... right ?

A subclass must accept anything the parent class can, but it can also make it stricter if you want.

class Base {
void foo(Object o) {}
}

class Derived : Base {
override void foo(const Object o) {}
}

That's legal because const also accepts mutable. Derived is stricter than Base which is permitted. But the other way around:

class Base {
void foo(const Object o) {}
}

class Derived : Base {
override void foo(Object o) {}
}

is NOT allowed because the mutable thing in derived cannot be passed back to the base interface implicitly.

July 17

On Saturday, 17 July 2021 at 22:48:00 UTC, Adam D Ruppe wrote:

>

On Saturday, 17 July 2021 at 22:43:15 UTC, someone wrote:

>

So the lesson learned is that interfaces can also mandate member function's parameter attributes then ... right ?

A subclass must accept anything the parent class can, but it can also make it stricter if you want.

class Base {
void foo(Object o) {}
}

class Derived : Base {
override void foo(const Object o) {}
}

That's legal because const also accepts mutable. Derived is stricter than Base which is permitted. But the other way around:

class Base {
void foo(const Object o) {}
}

class Derived : Base {
override void foo(Object o) {}
}

is NOT allowed because the mutable thing in derived cannot be passed back to the base interface implicitly.

Perfectly clear; thanks Adam :) !

July 18

On Saturday, 17 July 2021 at 21:01:00 UTC, Adam Ruppe wrote:

> >

From the interface perspective: are these signatures identical or not ?

No, they are very different.

This helped me solve an issue that I carried since a few days ago:

I have an interface with function members not being declared @safe (at first glance it seemed irrelevant to me just to mark @safe a declaration and not an actual implementation).

I also have former @safe member functions in classes implementing this interface that at some point I did have to take out the @safe declarations because the compiler didn't like them anymore due to some change I made which I didn't link to them, and from the on I did not quite understand why it was complaining since everything seemed perfect to me (as usual ha).

Now that I marked the ones in the interface @safe I can also mark the ones implementing them @safe again and now everything is @safe and working properly.

Another day, another lesson learned.

July 18

On Sunday, 18 July 2021 at 03:27:04 UTC, someone wrote:

>

I have an interface with function members not being declared @safe (at first glance it seemed irrelevant to me just to mark @safe a declaration and not an actual implementation).

Yeah, that'd be promising all child implementations are @safe.

Fun fact there: any child implementations do NOT need to specify the attribute there; the compiler will copy it from the interface for you.

interface I {
@safe void foo();
}

class C : I {
void foo(); // automatically copies @safe from interface
}

If you leave it off, you are not promising safe, but children are still allowed to use it anyway. The general rule is child classes can be stricter than the parent if they want to be, but they don't have to be.

interface I {
void foo(); // not safe
}

class C : I {
void foo(); // OK, not safe, interface didn't force it
}

class C2 : I {
@safe void foo(); // OK, class can be stricter than parent. now safe if used through C2, but the interface can't promise it is C2 instead of C, so it still follows @system rules.
}

class C3 : C2 {
override void foo(); // automatically @safe since it picks it up from parent C2
}

July 18

On Sunday, 18 July 2021 at 11:03:24 UTC, Adam D Ruppe wrote:

>

Fun fact there: any child implementations do NOT need to specify the attribute there; the compiler will copy it from the interface for you.

I suppose these are the day-to-day minor details you can rely on to avoid typing a lot of things, but, in the end, I prefer to state things clearly because in the event someone need to port my code I'll be making his life miserable trying to understand all these defaults; and I am not talking explicitly D here, I am talking any language, I did never forget a project in which I was involved porting a big development from C++ ... it took almost 3X the time we all think back then it needed to. From that time on I try to avoid fancy things with code whenever possible -just common sense.