November 21, 2022
On Monday, 21 November 2022 at 00:29:12 UTC, thebluepandabear wrote:
>> .. not to mention, I'd be out of job if I stopped writing getters/setters ;-)
>
> I value your input in this discussion, you have brought some good points.
>
> Out of interest, what type of industry-level software are you creating with D? I don't know much companies using D commercially.

As someone else mentioned in this thread, there are some 'arbitrary changes' in D, for example, to the traditional concept of the class type, as being a user-defined type for encapsulating data and methods that operate on that data.

That is, the module, not the class, is the unit of encapsulation in D.

In addition, public is the default visibility in a class in D, which also goes against the traditional concept of using an encapsulated user-defined data type in conjunction with 'information hiding' (or access controls, depending on what terminology you want to use).

These decisions no doubt, are design decisions, and not accidental, I presume.

These decisions have consequences of course.

You should be completely aware of these changes in D, *before* embarking on using classes in D. Some would say those consequences are benefical, while others would reject that proposition, entirely ;-)

As such I leave it to the designer(s) of D to better explain their reasoning.

These changes by themself rule out the use of D in our environment.

"..utility functions operating on data structures. Welcome to 1972!"

There are many other reasons also of course, which frankly are unrelated to (and more important) than the above.

But otherwise, I find D to be an enjoyable hobby language, particulary for lower-level programming, to both use and explore its capabilities.

There are of course some companies using it commercially. But not the company I work for.

November 21, 2022
On Sunday, 20 November 2022 at 12:23:39 UTC, Ali Çehreli wrote:
> ..
> Hm. 'private' is about access control. ....

It's unfortunate that phrase ('private') is used, both traditionally, and now (and yes, even by me).

A much better, clearer term, would be: 'interaction control', since that is what the programmer is really trying to achieve when inserting getters/setters into a class type.

i.e They are creating the specification for an encapulated object (data, and methods that operate on that data) with the necessary controls for 'interacting' with it.

On the otherhand, if the programmer is genuinely after 'access' control, then 'private' just won't do it ;-)

Also, D's 'arbitrary' changes, as mentioned in previous post, do not further progress the composition problem.

By that I mean, by enabling cooperative interactions within a module, D has also enabled potentially hazardous interactions as well, since you cannot enforce a perimeter around a class type from other code in the module. All code within a module, is within the bounds of that perimeter, at all times.

i.e. There is no way to enforce the principle of least privilege within a D module.

On that basis, I might be tempted to agree with you're point of view -> never, ever, ever, ever, use classes in D.

November 21, 2022

On Thursday, 17 November 2022 at 04:39:35 UTC, thebluepandabear wrote:

>

I am creating a TUI library and I have a class with the following constant fields:

class Label : Renderable {
    const string text;
    const TextAlignment textAlignment;
    const Color color;

    this(Dimensions dimensions, string text, TextAlignment textAlignment, Color color) {
        this.dimensions = dimensions;
        this(text, textAlignment, color);
    }

    this(string text, TextAlignment textAlignment, Color color) {
        this.text = text;
        this.textAlignment = textAlignment;
        this.color = color;
    }

    override Cell[] render() const {
        Cell[] cells;

        for (int x = 0; x < 0 + text.length; ++x) {
            cells ~= Cell(Coordinates(x, 0), text[x], color);
        }

        return cells;
    }
}

I am debating whether or not I should add getter methods to these properties. On one hand, it will inflate the codebase by a lot, on the other hand -- in other languages like Java it is a good practice:

class Label : Renderable {
    private const string text;
    private const TextAlignment textAlignment;
    private const Color color;

    this(Dimensions dimensions, string text, TextAlignment textAlignment, Color color) {
        this.dimensions = dimensions;
        this(text, textAlignment, color);
    }

    this(string text, TextAlignment textAlignment, Color color) {
        this.text = text;
        this.textAlignment = textAlignment;
        this.color = color;
    }

    string getText() const {
        return text;
    }

    TextAlignment getTextAlignment() const {
        return textAlignment;
    }

    Color getColor() const {
        return color;
    }

    override Cell[] render() const {
        Cell[] cells;

        for (int x = 0; x < 0 + text.length; ++x) {
            cells ~= Cell(Coordinates(x, 0), text[x], color);
        }

        return cells;
    }
}

It's not a lot of code that has been added but if you have a class with say 10 different fields, adding getter methods would definitely increase the code size by a lot, so what are you guys thoughts on this?

Dunno if someone mentioned, but you can minimize use of boilerplate by hiding it into mixin templates. Say you have:

mixin template Property(T) {
  private T subject_;

  T Property() { return subject_; }
  void Property(T value) { subject_ = value; }
}

The you can use it in your class to define properties of class:

class MyMegaPropertyClass {
  mixin Property!(string) myFancyProperty;
}

auto c = new MyMegaPropertyClass()

c.myFancyProperty = "indeed"

The only issue is that, by using eponymous naming you also block any access of underlying subject_ or any other miscellaneous info that you may add.

Best regards,
Alexandru.

November 21, 2022

On Monday, 21 November 2022 at 11:20:31 UTC, Alexandru Ermicioi wrote:

>

On Thursday, 17 November 2022 at 04:39:35 UTC, thebluepandabear wrote:

>

[...]

Dunno if someone mentioned, but you can minimize use of boilerplate by hiding it into mixin templates. Say you have:

mixin template Property(T) {
  private T subject_;

  T Property() { return subject_; }
  void Property(T value) { subject_ = value; }
}

The you can use it in your class to define properties of class:

class MyMegaPropertyClass {
  mixin Property!(string) myFancyProperty;
}

auto c = new MyMegaPropertyClass()

c.myFancyProperty = "indeed"

The only issue is that, by using eponymous naming you also block any access of underlying subject_ or any other miscellaneous info that you may add.

Best regards,
Alexandru.

You can use mixin templates to also define contlstructors, or any other boilerplate that is buildable using meta programming capabilities in D.

It would be awesome to have smth like Lombok from java but in D using mixin templates.

Best regards,
Alexandru

November 21, 2022
On 11/20/22 23:01, [] () {} () wrote:

> On that basis, I might be tempted to agree with you're point of view ->
> never, ever, ever, ever, use classes in D.

That's not my point of view.

Ali

November 21, 2022
>

Best regards,
Alexandru.

Thanks but I haven't reached that yet.

November 21, 2022
On 11/20/22 14:37, [] () {} () wrote:

> so, as I understand it, your're against the use of private, against the
> use of class, and against the use of encapsulation.

I never implied any of that.

> .. good luck with your career as a software engineer (but please, for
> all our sakes, don't work on any safety-related systems, and especially
> not the ones running in my car).

I haven't written any code that runs on the car yet but I did and still do work in autonomous vehicle projects:


https://techcrunch.com/2017/04/04/daimler-and-bosch-fully-autonomous-cars-within-5-years/

(That partnership is no more at this time.)

And coincidentally, to reply to your post that included Autosar, MISRA, etc. I am very well aware of those standards because I did contribute to the team that wrote our coding standards by going through every single one of their rules.

As one would expect, there was no argument on whether to use getters and setters or direct public access for that project: We decided no public access to members.

This discussion came to this point because you and I understood the question differently: I took the OP's question literally: "Is defining get/set methods for every field overkill?"

You took the question as whether to define them for class hierarchies, safety-critical systems, etc.

Ali

November 21, 2022

On Monday, 21 November 2022 at 11:34:50 UTC, thebluepandabear wrote:

> >

Best regards,
Alexandru.

Thanks but I haven't reached that yet.

Well, I wish you'll reach as soon as possible :)

November 21, 2022
On Monday, 21 November 2022 at 11:56:59 UTC, Ali Çehreli wrote:
> ..
> You took the question as whether to define them for class hierarchies, safety-critical systems, etc.
>
> Ali

Or even in a very, very simple counter class:


public synchronized class Counter
{
    static import core.atomic;

    private:
        int count = 0;

    public:
        void incrementCounter()
        {
            if ((count + 1) < 0)
            {
                // you might want to handle this
            }
            else
                core.atomic.atomicOp!"+="(this.count, 1);
        }

        int displayCounter()
        {
            return count;
        }
}

November 21, 2022
On Monday, 21 November 2022 at 23:25:21 UTC, []() {}() wrote:
> On Monday, 21 November 2022 at 11:56:59 UTC, Ali Çehreli wrote:
>> ..
>> You took the question as whether to define them for class hierarchies, safety-critical systems, etc.
>>
>> Ali
>
> Or even in a very, very simple counter class:
>
>
> public synchronized class Counter
> {
>     static import core.atomic;
>
>     private:
>         int count = 0;
>
>     public:
>         void incrementCounter()
>         {
>             if ((count + 1) < 0)
>             {
>                 // you might want to handle this
>             }
>             else
>                 core.atomic.atomicOp!"+="(this.count, 1);
>         }
>
>         int displayCounter()
>         {
>             return count;
>         }
> }

But why give a C++ code example? 🤨