September 30, 2021

On Thursday, 30 September 2021 at 12:55:48 UTC, Max Samukha wrote:

>

Yes, that is the semantics I would expect. Note the complication when vars from multiple scopes are captured:

int i = 1;
dgList ~= { writeln(i); };

while (i < 4) {
   immutable int n = i++;
   dgList ~= { writeln(i, " ", n); };
}

Expected:
4
4 1
4 2
4 3

That would require an implementation like this:

static struct __C0
{
    int i;
    void call() { writeln(i); }
}

auto c0 = new __C0(1);
dgList ~= &c0.call;

while (c0.i < 4) {
   static struct __C1 {
      __C0* c0;
      immutable int n;
      void call() { writeln(c0.i, " ", n); }
   }

   dgList ~= &(new __C1(c0, c0.i++)).call;
}

That is indeed the most expected behavior that is consistent with D's semantic in other areas of the language - notably construction/destruction and immutability.

September 30, 2021

On Thursday, 30 September 2021 at 11:32:28 UTC, Sebastiaan Koppe wrote:

>

On Thursday, 30 September 2021 at 11:00:15 UTC, deadalnix wrote:

>

D either needs to ditch constructor, destruction, immutable, and anything that has to do with lifetime.

I rather have closures that require you to state what you capture.

I'm not sure what that buys. If you undercapture, you get an error, if you overcapture, you get suboptimal code.

On the other hand,t he compiler always exactly knows what you capture and what you do not capture, so it can make the optimal choice without you having to state anything.

September 30, 2021

On Thursday, 30 September 2021 at 13:55:53 UTC, deadalnix wrote:

>

On Thursday, 30 September 2021 at 11:36:01 UTC, bauss wrote:

>

On Thursday, 30 September 2021 at 11:32:28 UTC, Sebastiaan Koppe wrote:

>

I rather have closures that require you to state what you capture.

I really like that in C++ because you don't clutter memory with unnecessary references. Your closure will only reference what you capture.

I have good news for you: the compiler knows what you capture and what you don't, so the only case where in which you'll have unnecessary reference, is if you capture explicitly and mess it up.

The upside with explicit capture is that you can specify you want a move/copy instead of a reference, side-stepping the OT's decade long problem.

September 30, 2021

On 9/30/21 9:55 AM, deadalnix wrote:

>

On Thursday, 30 September 2021 at 11:36:01 UTC, bauss wrote:

>

On Thursday, 30 September 2021 at 11:32:28 UTC, Sebastiaan Koppe wrote:

>

On Thursday, 30 September 2021 at 11:00:15 UTC, deadalnix wrote:

>

D either needs to ditch constructor, destruction, immutable, and anything that has to do with lifetime.

I rather have closures that require you to state what you capture.

I really like that in C++ because you don't clutter memory with unnecessary references. Your closure will only reference what you capture.

I have good news for you: the compiler knows what you capture and what you don't, so the only case where in which you'll have unnecessary reference, is if you capture explicitly and mess it up.

You may want to capture variables that would normally be referenced. The compiler can't possibly know what you want exactly.

Consider:

void delegate() dg;
for(int i = 0; i < 100; ++i)
{
   dg = { writeln(i); };
}

dg();

What i is printed? Note that there is only one i variable over the entire loop.

-Steve

September 30, 2021

On 9/30/21 10:42 AM, Steven Schveighoffer wrote:

>
void delegate() dg;
for(int i = 0; i < 100; ++i)
{
    dg = { writeln(i); };
}

dg();

Haha of course, I shouldn't overwrite the same delegate.

It should have been an array of delegates, but the point still stands.

-Steve

September 30, 2021
On Thursday, 30 September 2021 at 13:26:21 UTC, Tejas wrote:
> On Thursday, 30 September 2021 at 13:23:06 UTC, Imperatorn wrote:
>> On Thursday, 30 September 2021 at 01:00:40 UTC, deadalnix wrote:
>>> [...]
>>
>> Maybe, idk.
>>
>> But I don't understand why we can't just do what (for example) C# does.
>>
>> No var in loop = closure captures the variable
>> var in loop = closure captures the value of the variable
>>
>> Sounds to me like a pretty "easy" thing to fix (if one could agree that such a solution would be acceptible)
>
> Because Walter thinks that duplicating behavior like C#'s and other languages' will result in a huge performance hit, leading users to get very frustrated.
>
> Here's the link : https://forum.dlang.org/post/s83nb0$12rh$1@digitalmars.com

I understand the reasoning, but imo it's worth it to be able to write simpler code.

But on the other hand performance is ofc important. But on the third hand, if something is a hurdle for many to write correct code, it should be looked at again and re-evaluated.

Just my opinion
September 30, 2021

On Thursday, 30 September 2021 at 14:42:34 UTC, Steven Schveighoffer wrote:

>

Consider:

void delegate() dg;
for(int i = 0; i < 100; ++i)
{
   dg = { writeln(i); };
}

dg();

What i is printed? Note that there is only one i variable over the entire loop.

-Steve

It's a good example of things that the optimizer shoudl handle. In that specific case, you shouldn't expect any memory allocation because the delegate never escape.

September 30, 2021

On Thursday, 30 September 2021 at 14:44:52 UTC, Steven Schveighoffer wrote:

>

On 9/30/21 10:42 AM, Steven Schveighoffer wrote:

>
void delegate() dg;
for(int i = 0; i < 100; ++i)
{
    dg = { writeln(i); };
}

dg();

Haha of course, I shouldn't overwrite the same delegate.

It should have been an array of delegates, but the point still stands.

-Steve

In that case, you should expect all the delegates to print the same value. There is one i variable accross all loop iterations.

September 30, 2021

On Thursday, 30 September 2021 at 14:07:18 UTC, Sebastiaan Koppe wrote:

> >

I have good news for you: the compiler knows what you capture and what you don't, so the only case where in which you'll have unnecessary reference, is if you capture explicitly and mess it up.

The upside with explicit capture is that you can specify you want a move/copy instead of a reference, side-stepping the OT's decade long problem.

You can create a copy in a local variable though, if you need a capture by value.

Now, one thing that we might want are delegates with a strongly typed closure, as in C++. There are obvious downsides. To begin with, each delegate is of a different type and ABI.

If that is ever added to D, it should probably need to be a new feature, different from current delegates.

September 30, 2021
On Thursday, 30 September 2021 at 17:29:09 UTC, Imperatorn wrote:
> I understand the reasoning, but imo it's worth it to be able to write simpler code.

The reason you would want to use closures inside loops is to capture the loop variants, and therefore you agree to accept the performance hit. The current situation is that people whom Walter wanted to save from frustration don't use closures at all, and those who have a use for them are frustrated.

>
> But on the other hand performance is ofc important. But on the third hand, if something is a hurdle for many to write correct code, it should be looked at again and re-evaluated.
>
> Just my opinion


1 2 3 4
Next ›   Last »