May 15, 2018
On 5/15/18 7:53 AM, Yuxuan Shui wrote:
> On Friday, 11 May 2018 at 18:55:03 UTC, Meta wrote:
>> On Friday, 11 May 2018 at 15:03:41 UTC, Uknown wrote:
>>> [...]
>>
>> It's not as pretty, and I don't know if it works outside this toy example yet, but you can do:
>>
>> import std.stdio;
>>
>> struct Allocator
>> {
>>     auto call(alias F, Args...)(Args args)
>>     {
>>         return F(this, args);
>>     }
>>
>>     void deallocateAll()
>>     {
>>         writeln("deallocateAll");
>>     }
>> }
>>
>> void f1(Allocator a, int n) { writeln("f1"); }
>> void f2(Allocator, string s, double d) { writeln("f2"); }
>>
>> void main()
>> {
>>     with (Allocator())
>>     {
>>         scope(exit) deallocateAll;
>>         call!f1(2);
>>         call!f2("asdf", 1.0);
>>     }
>> }
> 
> I found another alternative to this:
> 
> https://godbolt.org/g/3Etims

Hm... neat idea. Somehow, opDispatch can probably be used to make this work even more generically (untested):

struct WithAlloc(alias alloc)
{
   auto opDispatch(string s, Args...)(auto ref Args args) if (__traits(compiles, mixin(s ~ "(args, alloc)")))
   {
      mixin("return " ~ s ~ "(args, alloc);");
   }
}

-Steve
May 15, 2018
On Friday, 11 May 2018 at 13:22:12 UTC, Meta wrote:
> On Friday, 11 May 2018 at 11:42:07 UTC, Dukc wrote:
>> On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:
>>> ...
>>> // constructor of DataStructure
>>> this(Allocator alloc=__ALLOC__) {...}
>>> ...
>>> auto alloc = new SomeAllocator();
>>> define __ALLOC__ = alloc;
>>> // And we don't need to pass alloc everytime
>>> ...
>>>
>>> Is this a good idea?
>>
>> Doesn't this basically mean including the implicits Martin Odersky talked about at Dconf in D?
>
> Yes it does. I was thinking the exact same thing while watching his talk; implicits would be perfect for allocators.

D doesn't have Scala's implicits though. However, one can write up a reader monad in the D we have right now.

Atila
May 15, 2018
On Tuesday, 15 May 2018 at 13:16:21 UTC, Steven Schveighoffer wrote:
> [snip]
>
> Hm... neat idea. Somehow, opDispatch can probably be used to make this work even more generically (untested):
>
> struct WithAlloc(alias alloc)
> {
>    auto opDispatch(string s, Args...)(auto ref Args args) if (__traits(compiles, mixin(s ~ "(args, alloc)")))
>    {
>       mixin("return " ~ s ~ "(args, alloc);");
>    }
> }
>
> -Steve

Example:
https://run.dlang.io/is/RV2xIH
May 15, 2018
On Tuesday, 15 May 2018 at 13:59:37 UTC, jmh530 wrote:
> On Tuesday, 15 May 2018 at 13:16:21 UTC, Steven Schveighoffer wrote:
>> [snip]
>>
>> Hm... neat idea. Somehow, opDispatch can probably be used to make this work even more generically (untested):
>>
>> struct WithAlloc(alias alloc)
>> {
>>    auto opDispatch(string s, Args...)(auto ref Args args) if (__traits(compiles, mixin(s ~ "(args, alloc)")))
>>    {
>>       mixin("return " ~ s ~ "(args, alloc);");
>>    }
>> }
>>
>> -Steve
>
> Example:
> https://run.dlang.io/is/RV2xIH

Sadly with(WithAlloc!alloc) doesn't work. (If you have to use withAlloc.func everywhere, it kind of destroy the point, doesn't it?)
May 15, 2018
On Tuesday, 15 May 2018 at 14:26:48 UTC, Yuxuan Shui wrote:
>> [snip]
>> Example:
>> https://run.dlang.io/is/RV2xIH
>
> Sadly with(WithAlloc!alloc) doesn't work. (If you have to use withAlloc.func everywhere, it kind of destroy the point, doesn't it?)

Yeah I know, I tried it, but couldn't figure out how to do the with statement with it.
May 15, 2018
On 5/15/18 10:26 AM, Yuxuan Shui wrote:
> On Tuesday, 15 May 2018 at 13:59:37 UTC, jmh530 wrote:
>> On Tuesday, 15 May 2018 at 13:16:21 UTC, Steven Schveighoffer wrote:
>>> [snip]
>>>
>>> Hm... neat idea. Somehow, opDispatch can probably be used to make this work even more generically (untested):
>>>
>>> struct WithAlloc(alias alloc)
>>> {
>>>    auto opDispatch(string s, Args...)(auto ref Args args) if (__traits(compiles, mixin(s ~ "(args, alloc)")))
>>>    {
>>>       mixin("return " ~ s ~ "(args, alloc);");
>>>    }
>>> }
>>>
>>> -Steve
>>
>> Example:
>> https://run.dlang.io/is/RV2xIH
> 
> Sadly with(WithAlloc!alloc) doesn't work. (If you have to use withAlloc.func everywhere, it kind of destroy the point, doesn't it?)

It seems opDispatch isn't being used in the with statement. That seems like a bug, or maybe a limitation. I'm not sure how "with" works, but I assumed it would try calling as a member, and then if it doesn't work, try the call normally. Probably it's checking to see if it has that member first.

Annoying...

-Steve
May 15, 2018
On Tuesday, 15 May 2018 at 14:52:46 UTC, Steven Schveighoffer wrote:
>> Sadly with(WithAlloc!alloc) doesn't work. (If you have to use withAlloc.func everywhere, it kind of destroy the point, doesn't it?)
>
> It seems opDispatch isn't being used in the with statement. That seems like a bug, or maybe a limitation. I'm not sure how "with" works, but I assumed it would try calling as a member, and then if it doesn't work, try the call normally. Probably it's checking to see if it has that member first.
>
> Annoying...
>
> -Steve

Yeah I tried it with opDispatch but it didn't work. I vaguely remember some changes being made to how lookup is done in the past year or so... but I can't find the PR in question.
May 15, 2018
On Tuesday, 15 May 2018 at 14:52:46 UTC, Steven Schveighoffer wrote:
> [snip]
>
> It seems opDispatch isn't being used in the with statement. That seems like a bug, or maybe a limitation. I'm not sure how "with" works, but I assumed it would try calling as a member, and then if it doesn't work, try the call normally. Probably it's checking to see if it has that member first.
>
> Annoying...
>
> -Steve

Looks like with statements ignore opDispatch.

struct Foo(int x)
{
    auto opDispatch(string s)()
        if (s == "bar")
    {
        return x++;
    }
}


void main()
{
    int y = 0;
    with(Foo!1)
    {
        y = bar; //error: undefined identifier bar
    }
    assert(y == 2);
}
May 15, 2018
On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:
> [snip]
>

Note, it's not an issue if Foo were not a struct. This was fixed in Bug 6400 [1]l. The issue is with template instances. I have filed a new enhancement request [2]

[1] https://issues.dlang.org/show_bug.cgi?id=6400
[2] https://issues.dlang.org/show_bug.cgi?id=18863
May 16, 2018
On Tuesday, 15 May 2018 at 20:31:14 UTC, jmh530 wrote:
> On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:
>> [snip]
>>
>
> Note, it's not an issue if Foo were not a struct. This was fixed in Bug 6400 [1]l. The issue is with template instances. I have filed a new enhancement request [2]
>
> [1] https://issues.dlang.org/show_bug.cgi?id=6400
> [2] https://issues.dlang.org/show_bug.cgi?id=18863

Interestingly, you can get pretty close with a struct nested in a template function, however it seems that overload resolution does not check opDispatch if a public symbol of the same name exists.

this (https://run.dlang.io/is/ZzfWDs) dosen't work, but this (https://run.dlang.io/is/7zvfqc) does (notice SList & DList are not directly visible).