November 19, 2022

On Saturday, 19 November 2022 at 04:37:51 UTC, thebluepandabear wrote:

>

Thankfully I only code in D as a hobby, so I don't need to use getters/setters! Thanks.

well, in that case, you can throw out everything that programmers have learnt over many decades, and just to whatever you want in your code.

But if you ever want to have users of your TUI Library, or want to have other developers contribute to it, you will want to follow reasonable guidelines.

Here is an example of a reasonable guideline (For C#, but can easily apply to D):

https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms229042(v=vs.100)

November 19, 2022
>

https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms229042(v=vs.100)

Thanks, I'll think about it more -- I am a noob so I may be wrong in what I am saying.

Of course in C# this argument wouldn't exist because you could just do { get; set; }, and I really wish D had something similar 😂

November 19, 2022

On Saturday, 19 November 2022 at 03:52:41 UTC, thebluepandabear wrote:

>

...
.....
Honestly, it may not be a magic bullet, but still useful.

This refactoring may be source compatible, but would it be binary compatible?

i.e. you refactor your class, compile it as an updated version of your library, then ship that updated library to your users.... will they then need to recompile their own code because of the refactoring you did?

In C#, I know the answer to that question.

As for D, I do not know (and I don't expect you to either ;-)

November 19, 2022

On Saturday, 19 November 2022 at 04:47:57 UTC, thebluepandabear wrote:

> >

https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms229042(v=vs.100)

Thanks, I'll think about it more -- I am a noob so I may be wrong in what I am saying.

Of course in C# this argument wouldn't exist because you could just do { get; set; }, and I really wish D had something similar 😂

It does.

private int myVariable;
public Get_myVariable(){}
public Set_myVariable(){}

those public Get/Set members functions are exactly what you get in C#, except the compiler does it for you, behind the scenes, saving you the keystokes.. but the end code is just as if you had typed them out yourself.

November 19, 2022

On Saturday, 19 November 2022 at 05:42:03 UTC, {}() wrote:

>

those public Get/Set members functions are exactly what you get in C#, except the compiler does it for you, behind the scenes, saving you the keystokes.. but the end code is just as if you had typed them out yourself.

I know...

November 19, 2022

On Saturday, 19 November 2022 at 04:47:57 UTC, thebluepandabear wrote:

>

..
Of course in C# this argument wouldn't exist because you could just do { get; set; }, and I really wish D had something similar 😂

If D had C#'s 'automatic' property syntax, it would as meaningless in D as it is in C# ;-)

If you used such, you would still need to completely refactor your class when you decided to implement you business rules (within the getter/setter), since you cannot do anything more than get and set with auto property.

Once you refactor your class (creating actual private member variables and creating getter/setter methods, you are almost certainly going to break binary compatability, and when you send your update compiler library to your customer, there code will stop working - cause they'll have to recompile it against the new library.

All this because some programmer wanted to save a few key strokes, or did not anticipate change, or did not anticipate the need to ensure data is valid before assigning it, or returning it.

So no. It's not overkill. It's called software engineering.

November 19, 2022

On Saturday, 19 November 2022 at 04:13:33 UTC, {}() wrote:

>

oh. so i get it now. you have to refactor your class (change member variable names and also do it in all places where they are used througout the class. then add new methods, overloading them in this way and that way, all because you're initial design never factored in the possibility of change (or even some validation of the vale being returned to the client, or validation of value coming from the client).

You are not required to rename everything, just actual members.

D has nice feature to convert foo.bar to foo.bar() and foo.bar = value to foo.bar(value) that doesn't exist in C/C++ for example. This reduces some headache in planning the API ahead.

Let's we have this class and its usage:

class Rect2D {
    int width;
    int height;

    auto area() const { return width * height; }
}

Rect2D rect = new Rect2D();
rect.width = 5;
rect.height = 5;

writeln(rect.area);   // note that this is seamlessly translated to rect.area()

Then you decided that you want getters/setters so you add them without changing anything:

class Rect2D {
    int width_;
    int height_;

    auto width() const { return width_; }
    void width(int w) { width_ = w; }

    auto height() const { return height_; }
    void height(int h) { height_ = h; }

    auto area() const { return width * height; }   // no changes here - using getters
}

Rect2D rect = new Rect2D();
rect.width = 5;   // no changes here - using setter
rect.height = 5;  // no changes here - using setter

writeln(rect.area);

You can also use UFCS instead of class members but it has a caveat: plain width/height won't work within class so you have to either use width_/height_ directly or this.width/this.height:

class Rect2D {
    int width_;
    int height_;

    auto area() const { return this.width * this.height; }  // UFCS calls to global width() and height() functions
}

// These functions have to be in global scope for UFCS to work
auto width(const Rect2D rect) { return rect.width_; }
void width(ref Rect2D rect, int w) { rect.width_ = w; }

auto height(const Rect2D rect) { return rect.height_; }
void height(ref Rect2D rect, int h) { rect.height_ = h; }

void main()
{
    // Still no changes in user code
    Rect2D rect = new Rect2D();
    rect.width = 5;
    rect.height = 5;

    writeln(rect.area);
}
November 19, 2022

That's the point many people have given here which is not convincing him, even though it is quite great.

I think we all know the answer here 😂

November 19, 2022

I respectfully disagree... It is not just a couple of keystrokes but rather thousands of lines that can be saved.

Let's just agree to disagree.

November 19, 2022

On Saturday, 19 November 2022 at 09:05:42 UTC, {}() wrote:

>

Once you refactor your class (creating actual private member variables and creating getter/setter methods, you are almost certainly going to break binary compatability, and when you send your update compiler library to your customer, there code will stop working - cause they'll have to recompile it against the new library.

I think you are speaking about shipping dynamic library to users. I think compiler authors can clarify whether introducing getters/setters breaks ABI or not. On the other side if it breaks then it can be easily checked: create simple program that uses dynamic library, then change the latter to use getters/setters and run program again without recompiling.