November 19, 2021

On Friday, 19 November 2021 at 15:39:54 UTC, 12345swordy wrote:

>

It violate encapsulation. Which at that point you might as well make the l-value public.

-Alex

It doesn't. Just like any other setter in any other language, it does not constraint you to return a private field in the object itself. You can return any value from any source, be it in object itself, a sub-object, on heap or on stack. The only constraint is to have it stored somewhere, so you can return a reference.

The main problem here, is that people expect for a value type to behave like a reference type here, which isn't the case in any other language too. Just try for example to return an int from a getter in java, and do ++ on it. You'll get the same behavior as in D.

Best regards,
Alexandru.

November 19, 2021

On Friday, 19 November 2021 at 16:14:41 UTC, Alexandru Ermicioi wrote:

>

It doesn't. Just like any other setter in any other language

I meant getter not setter.

Regards,
Alexandru

November 19, 2021

On Friday, 19 November 2021 at 16:14:41 UTC, Alexandru Ermicioi wrote:

>

On Friday, 19 November 2021 at 15:39:54 UTC, 12345swordy wrote:

>

It violate encapsulation. Which at that point you might as well make the l-value public.

-Alex

It doesn't. Just like any other setter in any other language, it does not constraint you to return a private field in the object itself. You can return any value from any source, be it in object itself, a sub-object, on heap or on stack. The only constraint is to have it stored somewhere, so you can return a reference.

The main problem here, is that people expect for a value type to behave like a reference type here, which isn't the case in any other language too. Just try for example to return an int from a getter in java, and do ++ on it. You'll get the same behavior as in D.

Best regards,
Alexandru.

class Square
{
    private double width;
    public double area()
    {
        return width * width;
    }
    public ref float area(double x)
    {
       width = sqrt(x);
      //what should I return here as ref?
    }
}

I don't know in Java, but in C# this works:


class Square
{
    private double width;
    public double area
    {
        get => width * width;
        set => width = Sqrt(value);
    }
    Square sq = new Square();
    sq.area += 1;
}
November 19, 2021

On Friday, 19 November 2021 at 16:14:41 UTC, Alexandru Ermicioi wrote:

>

On Friday, 19 November 2021 at 15:39:54 UTC, 12345swordy wrote:

>

It violate encapsulation. Which at that point you might as well make the l-value public.

-Alex

It doesn't.
Best regards,
Alexandru.

Yes it does, you are directly accessing to the variable itself here. The point of properties is to grant indirect access to it.

  • Alex
November 20, 2021

On Friday, 19 November 2021 at 16:31:19 UTC, rumbu wrote:

>
class Square
{
    private double width;
    public double area()
    {
        return width * width;
    }
    public ref float area(double x)
    {
       width = sqrt(x);
      //what should I return here as ref?
    }
}

Why should a setter return anything? (But of course it could, if you wish so).
This is not neccessary to realize the += operator.

I talked about the GETter that should not return a reference. Because the reason to have a getter (and no setter at all) is to make the value visible to the public, but not allow any hook to anything within my object. Beside the getter the object should remain a complete black box.
If any other behavior is desired, use something else than a getter property.
It's no problem to have ordinary members that return references and of which you can get the address or pointers or whatever. But properties should stay as close to the basic needs of a pure value as possible.
We don't need another way to write ordinary functions.

November 20, 2021

On Saturday, 20 November 2021 at 10:08:55 UTC, Dom DiSc wrote:

>

On Friday, 19 November 2021 at 16:31:19 UTC, rumbu wrote:

>
class Square
{
    private double width;
    public double area()
    {
        return width * width;
    }
    public ref float area(double x)
    {
       width = sqrt(x);
      //what should I return here as ref?
    }
}

Why should a setter return anything? (But of course it could, if you wish so).
This is not neccessary to realize the += operator.

I talked about the GETter that should not return a reference. Because the reason to have a getter (and no setter at all) is to make the value visible to the public, but not allow any hook to anything within my object. Beside the getter the object should remain a complete black box.
If any other behavior is desired, use something else than a getter property.
It's no problem to have ordinary members that return references and of which you can get the address or pointers or whatever. But properties should stay as close to the basic needs of a pure value as possible.
We don't need another way to write ordinary functions.

Please read the entire thread.

The original issue was the how can I design a property in D so I can write:

 area +=1;

The solution with ref return came from Atilla, not from me.

November 20, 2021

On Saturday, 20 November 2021 at 11:53:20 UTC, Rumbu wrote:

>

The original issue was the how can I design a property in D so I can write:

 area +=1;

import std.stdio;

struct Property(T) {
    T* t;

    T opOpAssign(string op)(T r)
    {
        mixin("(*t) "~op~"= r;");
        return *t;
    }
}

class Square
{
    private double width = 42;
    public auto area()
    {
        return Property!double(&width);
    }
}

void main() {
    auto s = new Square;
    writeln(s.width);
    s.area += 1;
    writeln(s.width);
}
November 20, 2021

On Saturday, 20 November 2021 at 12:11:14 UTC, Commander Zot wrote:

>

On Saturday, 20 November 2021 at 11:53:20 UTC, Rumbu wrote:

>

The original issue was the how can I design a property in D so I can write:

 area +=1;

import std.stdio;

struct Property(T) {
    T* t;

    T opOpAssign(string op)(T r)
    {
        mixin("(*t) "~op~"= r;");
        return *t;
    }
}

class Square
{
    private double width = 42;
    public auto area()
    {
        return Property!double(&width);
    }
}

void main() {
    auto s = new Square;
    writeln(s.width);
    s.area += 1;
    writeln(s.width);
}

Try again. Width must be 42.01 after you increase area by 1, not 43.

And again, it's not about that you can find or not an workaround, it's about the fact that @property is half baked in the language.

November 20, 2021

On Saturday, 20 November 2021 at 13:32:40 UTC, Rumbu wrote:

>

On Saturday, 20 November 2021 at 12:11:14 UTC, Commander Zot wrote:

>

On Saturday, 20 November 2021 at 11:53:20 UTC, Rumbu wrote:

>

The original issue was the how can I design a property in D so I can write:

 area +=1;

import std.stdio;

struct Property(T) {
    T* t;

    T opOpAssign(string op)(T r)
    {
        mixin("(*t) "~op~"= r;");
        return *t;
    }
}

class Square
{
    private double width = 42;
    public auto area()
    {
        return Property!double(&width);
    }
}

void main() {
    auto s = new Square;
    writeln(s.width);
    s.area += 1;
    writeln(s.width);
}

Try again. Width must be 42.01 after you increase area by 1, not 43.

And again, it's not about that you can find or not an workaround, it's about the fact that @property is half baked in the language.

this was just an example how you can actually implement properties that support whatever operation you want. @property and the assignment rewrite should just be removed from the language in my opinion.

November 20, 2021

On Friday, 19 November 2021 at 10:21:35 UTC, Max Samukha wrote:

>

On Thursday, 18 November 2021 at 19:32:36 UTC, Atila Neves wrote:

>

Works with ref prop() { return _fld; }.

The whole point of properties is to hide private state.

I don't agree - I think the point is to treat getters like state.

>

Exposing a private member for direct mutation is generally a bad idea.

I agree wholeheartedly. Getters are a code smell, setters stink.