callback craziness

Engine Machine via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 7 17:42:47 PDT 2016


On Sunday, 7 August 2016 at 23:02:26 UTC, ag0aep6g wrote:
> On 08/08/2016 12:08 AM, Engine Machine wrote:
>> On Sunday, 7 August 2016 at 20:48:29 UTC, ag0aep6g wrote:
> [...]
>>> Delegates don't necessarily need a GC allocation. They only 
>>> need it
>>> when they need a closure. Delegates of methods don't need 
>>> closures.
>>> And when you pass the delegate in a `scope` parameter, no 
>>> closure is
>>> needed, either.
>>
>> Well, one can't pick the case the delegate is passed. When I 
>> use a
>> delegate in the nogc context it errs.
>
> Not exactly. When you do something that requires a closure, it 
> errors out. As I said, a delegate doesn't always require the 
> allocation of a closure.
>
> This works just fine, and it uses a delegate parameter:
>
> ----
> @nogc void foo(void delegate(int x) @nogc f) {}
>
> void main() @nogc
> {
>     foo((int x) {});
>
>     struct S
>     {
>         int y;
>         void f(int x) @nogc { this.y = x; }
>     }
>     S s;
>     foo(&s.f);
> }
> ----
>
> But this doesn't compile, because the delegate here would need 
> a closure:
>
> ----
> @nogc void foo(void delegate(int x) @nogc f) {}
>
> void main() @nogc
> {
>     int y;
>     foo((int x) { y = x; });
> }
> ----
>
> Also note that it's main's @nogc that makes this fail, not 
> foo's or the parameter's. Remove main's @nogc and it works.
>
> [...]
>>> You're missing an argument there. The second parameter of foo 
>>> is
>>> `args` which is `string` here. This call works:
>>>
>>>     foo!string((int x, string s) { }, "", 1);
>>>
>>
>> Yeah, that was just a typeo obvious. That's not the reason it 
>> fails.
>
> No. It's exactly the reason it fails. Add a string argument and 
> it works:
>
> ----
> alias callback(Args) = @nogc void function(int x, Args);
> @nogc void foo(Args...)(callback!Args f, auto ref Args args, 
> int extra = 0) {}
>
> void main() @nogc
> {
>     foo!string((int x, string s) { }, "", 1);
> }
> ----
>
> [...]
>>> One thing you need to fix: The `callback` template needs a 
>>> template
>>> sequence parameter (i.e. `Args...`). Otherwise it takes 
>>> exactly one type.
>>
>> I did try that first and it didn't work. it works without ..., 
>> and I
>> figured that it is a template parameter and can also represent 
>> a
>> sequence?
>
> No, without `...`, the template parameter only accepts exactly 
> one type, not more than one, not none.


So, what about passing in the lambda verses the temp variable?

I tried the ... same problem as I said.

f!()(...) doesn't work.

Everything works find as long as I pass more than one variable.


My code is as follows and I cannot get 0 parameters working nor 
passing the function in directly. These were my original 
questions to begin with and haven't been answered. Here is the 
code I am using.

alias callback(Args...) = @nogc void function(string, int, Args);
@nogc public void foo(Args...)(callback!Args c, Args args, int x) 
{ }

foo((string s, int i) { }, 1);

does not work

nor does

foo!()((string s, int i) { }, 1);


Ultimately it would also be nice if the template parameters were 
deduced automatically instead of having to specify them. The 
compiler should be able to figure out the types supplied 
parameters.

e.g.,

foo((string s, int i, T x) { }, someT, 1);

instead of

foo!(T)((string s, int i, T x) { }, someT, 1);

should it not?




	


More information about the Digitalmars-d-learn mailing list