October 24
On 10/24/24 01:00, Elias (0xEAB) wrote:
> On Sunday, 20 October 2024 at 22:45:24 UTC, Timon Gehr wrote:
>> As someone who has also implemented `opApply`, I do think it is quite straightforward. It's just internal iteration with support for multiple ways to exit the loop, encoded using numerical indices.
> 
> Do you have any suggestions or insights how we could resolve its rather poor compatibility with the attribute soup?

Attribute polymorphism. It's a common feature in other effect systems, and it is generally useful.

Another solution is to avoid attributes. :)
October 24
On Thursday, 24 October 2024 at 00:46:48 UTC, Timon Gehr wrote:

>
> Another solution is to avoid attributes. :)

The only practical one.
October 24
On Thursday, 24 October 2024 at 00:46:48 UTC, Timon Gehr wrote:
> On 10/24/24 01:00, Elias (0xEAB) wrote:
>> On Sunday, 20 October 2024 at 22:45:24 UTC, Timon Gehr wrote:
>>> As someone who has also implemented `opApply`, I do think it is quite straightforward. It's just internal iteration with support for multiple ways to exit the loop, encoded using numerical indices.
>> 
>> Do you have any suggestions or insights how we could resolve its rather poor compatibility with the attribute soup?
>
> Attribute polymorphism. It's a common feature in other effect systems, and it is generally useful.
>
> Another solution is to avoid attributes. :)

Do you count languages with effects systems like Koka count as having effect polymorphism? I've studied them a bit, and it is a deep, deep rabbit hole that D could go down for not that much benefit. Or would you limit such a system to something like:

void map(T, U, effect Es...)(t[] a, U function(T) <Es> fun) <Es>; // Strawman syntax, I dunno

Where it's solely polymorphism over effects and there isn't all this complicated stuff like effect types and handlers, etc.
October 30

On Sunday, 20 October 2024 at 02:14:14 UTC, Steven Schveighoffer wrote:

>

I thought of this when someone asked the age-old question about closures not capturing loop variables.

https://gist.github.com/schveiguy/b6b037bdfe74997743de81f8d3f4b92b

For the most part, I prefer Timon's solution in the Bugzilla issue. For this particular example, it would be

void main()
{   import std.stdio;
    void delegate()[] dgs;

    foreach(i; [1, 2, 3, 4])
    {   dgs ~= (x => () => writeln(x))(i);
    }
    foreach(d; dgs) d(); // 1, 2, 3, 4
}

I prefer this trick mostly because it also lets you to catch other things than just the element being iterated over.

6 days ago
On 10/20/24 8:41 PM, Walter Bright wrote:

> That's because you're smarter than I am, Timon. And I'm not joking.

I am happy to be smart enough to see that you are right. :o)

> I implemented it as a way to deal with visiting each node of a binary tree. Doing that with a range is clunky and unappealing.

Exactly! I've always thought opApply is one of the most brilliant parts of D. It's easy to see the curly braces of the foreach loop as a lambda anyway.

Ali

6 days ago
On 20/11/2024 5:43 AM, Ali Çehreli wrote:
>     I implemented it as a way to deal with visiting each node of a
>     binary tree. Doing that with a range is clunky and unappealing.
> 
> Exactly! I've always thought opApply is one of the most brilliant parts of D. It's easy to see the curly braces of the foreach loop as a lambda anyway.

There are other ways to do it, than just giving it a delegate.

I.e. hidden state struct and then range over it.

Still on my todo list to look into, as it solves the attribute problem of opApply also.

5 days ago
On 11/19/24 8:50 AM, Richard (Rikki) Andrew Cattermole wrote:
> On 20/11/2024 5:43 AM, Ali Çehreli wrote:

>> I've always thought opApply is one of the most brilliant
>> parts of D. It's easy to see the curly braces of the foreach loop as a
>> lambda anyway.
>
> There are other ways to do it, than just giving it a delegate.
>
> I.e. hidden state struct and then range over it.
>
> Still on my todo list to look into, as it solves the attribute problem
> of opApply also.

Please also keep in mind, as mentioned elsewhere in this thread, e.g. tree traversal is trivial with opApply but not with ranges. That's because the delegate is there to call regardless of how deeply recursed we are in traversal. With ranges, a range must maintain the state of traversing.

So, I guess both styles have their strong points.

Ali

5 days ago
On 20/11/2024 10:43 AM, Ali Çehreli wrote:
> On 11/19/24 8:50 AM, Richard (Rikki) Andrew Cattermole wrote:
>  > On 20/11/2024 5:43 AM, Ali Çehreli wrote:
> 
>  >> I've always thought opApply is one of the most brilliant
>  >> parts of D. It's easy to see the curly braces of the foreach loop as a
>  >> lambda anyway.
>  >
>  > There are other ways to do it, than just giving it a delegate.
>  >
>  > I.e. hidden state struct and then range over it.
>  >
>  > Still on my todo list to look into, as it solves the attribute problem
>  > of opApply also.
> 
> Please also keep in mind, as mentioned elsewhere in this thread, e.g. tree traversal is trivial with opApply but not with ranges. That's because the delegate is there to call regardless of how deeply recursed we are in traversal. With ranges, a range must maintain the state of traversing.
> 
> So, I guess both styles have their strong points.
> 
> Ali

Indeed, its not something I'd consider for normal data structures (I think the only place I use them as greedy with recursive calling, is in my allocators). It's not a pattern that immediately comes to mind.

In saying that, yeah there are reasons to want opApply in its current form, and given the amount of code that uses it already I was never on the side of removal :)

In terms of transversal:

```d
struct S {
	DS* ds;
	Node* node;

	ref V front() {
		return node.value;
	}
}

s.front
```

Is no different than:

```d
{
	Node* node;

	del(node.value);
}
```

You have split out the already existing state that's stored in the function out of it.

So you can do a ton of what opApply does today with this approach.

4 days ago

On Sunday, 20 October 2024 at 17:48:15 UTC, Paul Backus wrote:

>

On Sunday, 20 October 2024 at 02:14:14 UTC, Steven Schveighoffer wrote:

>

I thought of this when someone asked the age-old question about closures not capturing loop variables.

https://gist.github.com/schveiguy/b6b037bdfe74997743de81f8d3f4b92b

How does it work? It works because opApply is passed a lambda function generated by the compiler to implement the foreach body.

But because this is a separate function, when you close over that lambda, the lambda's stack is independently allocated on the heap for each loop iteration.

This is cute and all, but the correct solution is to fix the damn compiler. The fact that this is necessary in the first place is an embarrassment.

Indeed

1 2
Next ›   Last »