Thread overview
Avoiding GC in D and code consistancy
Dec 31, 2017
Tim Hsu
Dec 31, 2017
Ali Çehreli
Dec 31, 2017
Tim Hsu
Dec 31, 2017
Seb
December 31, 2017
I came from C++ looking forward to D. Some languages require programmers to use GC all the time. However, A lot of time we don't really need GC especially when the time of destruction is deterministic in compile time.

I found that struct in D is allocate on stack by default. And we can use scope! to allocate class on stack too.

See the following code. Struct version of Vector3f can't derive toString method. writeln() prints unformated struct members. I know I can use helper function here. But is there any other way?

struct Vector3f {
public:
    this(float x, float y, float z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    @property float length2() {
        return x*x+y*y+z*z;
    }

    @property float length() {
        import std.math;
        return sqrt(x*x+y*y+z*z);
    }

    Vector3f opBinary(string op)(Vector3f rhs)
    {
        static if (op == "+") return Vector3f(x+rhs.x, y+rhs.y, z+rhs.z);
        else static if (op == "-") return Vector3f(x-rhs.x, y-rhs.y, z-rhs.z);
        else static assert(0, "Operator "~op~" not implemented");
    }

    float x, y, z;
}

class version of Vector3f. Require new operator in opBinary(). scoped! won't work here.

Is there a better to write vector3f class while avoiding GC?
December 30, 2017
On 12/30/2017 11:16 PM, Tim Hsu wrote:

> Struct version of Vector3f can't derive toString
> method. writeln() prints unformated struct members. I know I can use
> helper function here. But is there any other way?

The normal way that I know is to insert a function like the following into Vector3f:

    string toString() {
        import std.string : format;
        return format("%s,%s,%s", x, y, z);
    }

> class version of Vector3f. Require new operator in opBinary(). scoped!
> won't work here.
>
> Is there a better to write vector3f class while avoiding GC?

Yeah, it doesn't make sense that a type of x, y, z should be a class. I would stay with a struct here.

Ali

December 31, 2017
On Sunday, 31 December 2017 at 07:32:50 UTC, Ali Çehreli wrote:
> On 12/30/2017 11:16 PM, Tim Hsu wrote:
>
> > Struct version of Vector3f can't derive toString
> > method. writeln() prints unformated struct members. I know I
> can use
> > helper function here. But is there any other way?
>
> The normal way that I know is to insert a function like the following into Vector3f:
>
>     string toString() {
>         import std.string : format;
>         return format("%s,%s,%s", x, y, z);
>     }
>
> > class version of Vector3f. Require new operator in
> opBinary(). scoped!
> > won't work here.
> >
> > Is there a better to write vector3f class while avoiding GC?
>
> Yeah, it doesn't make sense that a type of x, y, z should be a class. I would stay with a struct here.
>
> Ali

Sorry I am a bit disappointed. It seems writeln itself will check if the struct to be printed has toString. If not, it use default struct printer.
December 31, 2017
On Sunday, 31 December 2017 at 07:16:46 UTC, Tim Hsu wrote:
> I came from C++ looking forward to D. Some languages require programmers to use GC all the time. However, A lot of time we don't really need GC especially when the time of destruction is deterministic in compile time.
>
> [...]

You can use a custom toString method which doesn't do any allocations:

https://wiki.dlang.org/Defining_custom_print_format_specifiers

However, the building blocks (formattedWrite and writeln) aren't "@nogc" at the moment.
December 31, 2017
On 12/31/17 6:16 AM, Tim Hsu wrote:
> On Sunday, 31 December 2017 at 07:32:50 UTC, Ali Çehreli wrote:
>> On 12/30/2017 11:16 PM, Tim Hsu wrote:
>>
>> > Struct version of Vector3f can't derive toString
>> > method. writeln() prints unformated struct members. I know I
>> can use
>> > helper function here. But is there any other way?
>>
>> The normal way that I know is to insert a function like the following into Vector3f:
>>
>>     string toString() {
>>         import std.string : format;
>>         return format("%s,%s,%s", x, y, z);
>>     }
>>
>> > class version of Vector3f. Require new operator in
>> opBinary(). scoped!
>> > won't work here.
>> >
>> > Is there a better to write vector3f class while avoiding GC?
>>
>> Yeah, it doesn't make sense that a type of x, y, z should be a class. I would stay with a struct here.
>>
> 
> Sorry I am a bit disappointed. It seems writeln itself will check if the struct to be printed has toString. If not, it use default struct printer.

Note, you can use a "sink" version of toString as well, and avoid the gc:

void toString(void delegate(const(char)[]) sink) @nogc
{
    // use formatValue to push into the sink
}

-Steve
December 31, 2017
On 12/31/17 7:50 AM, Steven Schveighoffer wrote:

> Note, you can use a "sink" version of toString as well, and avoid the gc:
> 
> void toString(void delegate(const(char)[]) sink) @nogc
> {
>      // use formatValue to push into the sink
> }

I guess I'm missing some parameters here, go with what Seb linked to :)

-Steve