Thread overview
Anonymous nogc class
Sep 07, 2017
Jiyan
Sep 08, 2017
Biotronic
Sep 08, 2017
Jiyan
Sep 08, 2017
Biotronic
Sep 08, 2017
Jiyan
September 07, 2017
Hey,
wanted to know whether it is possible to make anonymous nogc classes:

interface I
{
	public void ap();
}
void exec(I i)
{
	i.ap;
}

// now execute, but with something like `scope`
exec( new  class  I
{
	int tr = 43;
	override void ap(){tr.writeln;}
});

Thanks :)
September 08, 2017
On Thursday, 7 September 2017 at 23:40:11 UTC, Jiyan wrote:
> Hey,
> wanted to know whether it is possible to make anonymous nogc classes:
>
> interface I
> {
> 	public void ap();
> }
> void exec(I i)
> {
> 	i.ap;
> }
>
> // now execute, but with something like `scope`
> exec( new  class  I
> {
> 	int tr = 43;
> 	override void ap(){tr.writeln;}
> });
>
> Thanks :)

Sadly, even std.typecons.scoped isn't currently @nogc:
https://issues.dlang.org/show_bug.cgi?id=13972
https://issues.dlang.org/show_bug.cgi?id=17592

This can be worked around by casting scoped's destructor to be @nogc, but that's a heavy-handed approach that ruins type safety, and is the wrong solution in non-@nogc situations. Should you want to, this is what it should look like:

        ~this()
        {
            (cast(void delegate(T) @nogc)((T t){
                // `destroy` will also write .init but we have no functions in druntime
                // for deterministic finalization and memory releasing for now.
                .destroy(t);
            }))(Scoped_payload);
        }

If and when this issue is resolved, this should work:

interface I {
    public void ap();
}

void exec(I i) {
    i.ap;
}

auto scopedAnon(T)(lazy T dummy) if (is(T == class)) {
    import std.typecons;
    return scoped!T();
}

unittest {
    auto i = scopedAnon(new class I {
        int tr = 43;
        override void ap() {
            import std.stdio;
            tr.writeln;
        }
    });
    exec(i);
}

--
  Biotronic
September 08, 2017
On Friday, 8 September 2017 at 06:37:54 UTC, Biotronic wrote:
> On Thursday, 7 September 2017 at 23:40:11 UTC, Jiyan wrote:
>> [...]
>
> Sadly, even std.typecons.scoped isn't currently @nogc:
> https://issues.dlang.org/show_bug.cgi?id=13972
> https://issues.dlang.org/show_bug.cgi?id=17592
>
> [...]

First thanks :)

i understand the part with scopedAnon, but can you explain what the ~this is referring to?
Is it the Modul destructor?
And in general is it just that scoped is just not marked @nogc or is it that it would really need to use the gc?
September 08, 2017
On Friday, 8 September 2017 at 12:32:35 UTC, Jiyan wrote:
> On Friday, 8 September 2017 at 06:37:54 UTC, Biotronic wrote:
>> On Thursday, 7 September 2017 at 23:40:11 UTC, Jiyan wrote:
>>> [...]
>>
>> Sadly, even std.typecons.scoped isn't currently @nogc:
>> https://issues.dlang.org/show_bug.cgi?id=13972
>> https://issues.dlang.org/show_bug.cgi?id=17592
>>
>> [...]
>
> First thanks :)
>
> i understand the part with scopedAnon, but can you explain what the ~this is referring to?
> Is it the Modul destructor?

It's scoped!T's destructor. If you decide to use that workaround, you should probably copy scoped!T from std.typecons and have your own version. It's not safe in all cases, and the next standard library update might break it.

> And in general is it just that scoped is just not marked @nogc or is it that it would really need to use the gc?

In your case, scoped!T is can be safely called from @nogc code, and thus could be marked @nogc. However, when a class C has a destructor that allocates, scoped!C could not be @nogc. So in order to be safe in all cases, it can't be @nogc in the general case.

--
  Biotronic
September 08, 2017
On Friday, 8 September 2017 at 16:10:55 UTC, Biotronic wrote:
> On Friday, 8 September 2017 at 12:32:35 UTC, Jiyan wrote:
>> [...]
>
> It's scoped!T's destructor. If you decide to use that workaround, you should probably copy scoped!T from std.typecons and have your own version. It's not safe in all cases, and the next standard library update might break it.
>
>> [...]
>
> In your case, scoped!T is can be safely called from @nogc code, and thus could be marked @nogc. However, when a class C has a destructor that allocates, scoped!C could not be @nogc. So in order to be safe in all cases, it can't be @nogc in the general case.
>
> --
>   Biotronic

Thank you very much :)