Jump to page: 1 2 3
Thread overview
[Issue 5710] cannot use delegates as parameters to non-global template
Jun 05, 2014
timon.gehr@gmx.ch
Jun 10, 2014
Sobirari Muhomori
Jun 10, 2014
Martin Nowak
Jun 10, 2014
Martin Nowak
Jun 10, 2014
deadalnix
Jun 11, 2014
Sobirari Muhomori
Jun 14, 2014
Sobirari Muhomori
Jun 14, 2014
timon.gehr@gmx.ch
Jun 17, 2014
Sobirari Muhomori
Aug 18, 2014
Vladimir Panteleev
Mar 31, 2015
Maksim Zholudev
Dec 12, 2016
Martin Nowak
Dec 12, 2016
Martin Nowak
Nov 17, 2017
calex
Feb 16, 2018
Simen Kjaeraas
Jan 09, 2019
ZombineDev
Jan 09, 2019
Seb
Apr 12, 2019
Dlang Bot
Apr 24, 2019
Dlang Bot
Jun 26, 2019
Dennis
Apr 14, 2020
Dlang Bot
Jan 07
Dlang Bot
Jan 12
Bolpat
June 05, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #32 from timon.gehr@gmx.ch ---
(In reply to Kenji Hara from comment #29)
> ...
> 
> #1 is necessary for the multiple-context delegates. But applying same rule for existing one-context delegates

There is no particular reason to apply the same rule for existing one-context delegates. Those work already.

> will add hidden runtime cost against existing code.
> ...

Hence it seems like a bad idea to apply the same rule for existing one-context delegates.

> To avoid the cost, ...

There is no need to introduce it in the first place.

--
June 10, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #33 from Sobirari Muhomori <dfj1esp02@sneakemail.com> ---
A slightly more straightforward solution: the passed context is effectively a closure, and it can contain any variables, so let's just pass this pointer in the closure context struct. All the rules of closures apply.

struct main_add_closure_context
{
  auto var1;
  auto var2;
  Foo foo_this;
  auto var3;
  auto var4;
}

This context is like any normal closure, the `add` can simply use it. Also pass it instead of `this` argument to doStuff(alias fun), which in its turn should be taught to get `this` reference from the passed context struct.

--
June 10, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #34 from Martin Nowak <code@dawg.eu> ---
(In reply to Sobirari Muhomori from comment #33)
> A slightly more straightforward solution: the passed context is effectively a closure, and it can contain any variables, so let's just pass this pointer in the closure context struct. All the rules of closures apply.
> 
> struct main_add_closure_context
> {
>   auto var1;
>   auto var2;
>   Foo foo_this;
>   auto var3;
>   auto var4;
> }
> 
> This context is like any normal closure, the `add` can simply use it. Also pass it instead of `this` argument to doStuff(alias fun), which in its turn should be taught to get `this` reference from the passed context struct.

Yes, this is similar to comment 31 and it should work using the normal delegate pointer. It's still challenging to implement all the IR gen for this.

--
June 10, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #35 from Martin Nowak <code@dawg.eu> ---
(In reply to Kenji Hara from comment #29)
> (In reply to comment #27)
> > (In reply to comment #26)
> > > (In reply to comment #25)
> > > > Good to see, that you already know this solution.
> > > > I think the biggest hurdle to implement is teaching the IR/backend to get
> > > > doStuff's this pointer from an array.
> > > 
> > > Unfortunately it is merely an idea, and it would break existing delegate ABI.
> > 
> > How would it break the existing delegate ABI?
> 
> Sorry, it was not good words. It will break some existing assumptions around delegate. For example:
> 
> class C {
>   void foo() {}
>   void bar(alias fun)() {}
> }
> void test()
> {
>   C c = new C();
>   auto dg1 = &c.foo;
> 
> /* currently upsupported case.
> 
>     void nested() {}
>     auto dg2 = &c.bar!nested;
>     dg2();
> 
>    #1. dg2.ptr cannot become c.
>    Instead, it should point to the "context pointer list".
>    But, if dg2 is returned from the function 'test', the list
>    should be allocated on heap.
>  */
> }
> 
> #1 is necessary for the multiple-context delegates. But applying same rule for existing one-context delegates will add hidden runtime cost against existing code.
> 
> To avoid the cost, we should introduce the second delegate type for the multiple-context delegates. Then, the typeof(dg1) and typeof(dg2) will become incompatible. It will make D's type system more complicated.
> 
> Therefore, I had withdrawn my idea. It won't add enough benefits compared with the necessary complexity.

The type will be 'delegate void()' for both cases. True, 'dg1.ptr is c' and
'dg2.ptr !is c', but that doesn't affect the type as we don't inherit C++'s
member pointer complexity. The function 'void bar(alias fun)()' can access the
this pointer through 'dg2.ptr'.

--
June 10, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #36 from deadalnix <deadalnix@gmail.com> ---
Just putting that here:
http://wiki.dlang.org/DIP30

--
June 11, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #37 from Sobirari Muhomori <dfj1esp02@sneakemail.com> ---
(In reply to Martin Nowak from comment #34)
> Yes, this is similar to comment 31 and it should work using the normal delegate pointer. It's still challenging to implement all the IR gen for this.

My proposal is to have single context instead of multicontext - should have less difficulty for the caller - no need to generate the array, only a normal closure context.

--
June 14, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #38 from Sobirari Muhomori <dfj1esp02@sneakemail.com> ---
(In reply to Martin Nowak from comment #34)
> It's still challenging to implement all the IR gen for this.

BTW, looks like all the code generation was there for ages:

struct A
{
    int a;
    int delegate() foo()
    {
        int b;
        int bar()
        {
            return a+b;
        }
        int delegate() d=&bar;
        b=1;
        return d;
    }
}

Here nested function `bar` accesses both stack variable `b` and member field `a` through single context pointer in delegate `d` as if it has two contexts - closure pointer and `this` pointer.

--
June 14, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #39 from timon.gehr@gmx.ch ---
(In reply to Sobirari Muhomori from comment #38)
> (In reply to Martin Nowak from comment #34)
> > It's still challenging to implement all the IR gen for this.
> 
> BTW, looks like all the code generation was there for ages:
> 
> struct A
> {
> 	int a;
> 	int delegate() foo()
> 	{
> 		int b;
> 		int bar()
> 		{
> 			return a+b;
> 		}
> 		int delegate() d=&bar;
> 		b=1;
> 		return d;
> 	}
> }
> 
> Here nested function `bar` accesses both stack variable `b` and member field `a` through single context pointer in delegate `d` as if it has two contexts - closure pointer and `this` pointer.

This is not the same thing. Here, one context is nested in the other.

--
June 17, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

--- Comment #40 from Sobirari Muhomori <dfj1esp02@sneakemail.com> ---
This is exactly my point: don't make it a different thing. The function needs two contexts, they can be nested, backend and frontend can construct and access such nested contexts, no need to reimplement it in a different way.

--
August 18, 2014
https://issues.dlang.org/show_bug.cgi?id=5710

Vladimir Panteleev <thecybershadow@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |thecybershadow@gmail.com

--- Comment #41 from Vladimir Panteleev <thecybershadow@gmail.com> ---
Added $50 to existing $100 bounty: https://www.bountysource.com/issues/1375082-cannot-use-delegates-as-parameters-to-non-global-template

--
« First   ‹ Prev
1 2 3