Address of a lambda

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jul 7 11:01:59 PDT 2017


On 07/07/2017 07:33 PM, FoxyBrown wrote:
> In gtk, we routinly have to use delegates for callbacks. But the methods 
> that accept these delegates want the address of the delegate,

I don't think that's true. As far as I can tell, this is the signature 
of addOnDelete [1]:

----
gulong addOnDelete(bool delegate(Event, Widget) dlg, ConnectFlags 
connectFlags=cast(ConnectFlags)0)
----

`dlg` is just a delegate, not a pointer to a delegate.

> this 
> prevents us from being able to pass a lambda in directly, but there 
> really is not reason why we shouldn't be able to do this?
> 
> Fine:
> void main()
> {
> bool windowDelete(Event event, Widget widget) {    Main.quit(); return 
> false; }
> MainWindow.addOnDelete(&windowDelete);
> }

Here you're "taking the address" of a method. The result is a delegate, 
not a pointer to a delegate. The delegate is the address/pointer (plus 
another pointer to some related context).

> Invalid:
> 
> void main()
> {
> MainWindow.addOnDelete(&((Event event, Widget widget) {    Main.quit(); 
> return false; }));
> }

Remove the `&` operator and it should work. The function literal [2] 
already makes a delegate.

> and yet, the only difference is a copy and paste(i.e., a rewrite rule, 
> at most). Surely the compiler can figure out that we can take such an 
> address because anything that actually exists must have an address 
> somewhere.

Stuff can exist in registers only. In a function call `f(42)`, 42 likely 
goes directly into a register, not into memory.

> Seems like an arbitrary blocker? Even if it saves us from 
> some obscure problems, it should work in most cases and be allowed when 
> used in those cases.
> 
> What's even stranger is that the function windowDelete must be declared 
> in some type of object, such as another function, so it is actually a 
> delegate, if one has it in the module root then it is a normal function 
> and cannot be passed to addOnDelete, even though, again, there is very 
> little difference.

Yeah, that's an interesting oddity. The problem is that the parameters 
of a `void delegate(int foo, int bar)` are possibly passed differently 
from those of a `void function(int foo, int bar)`.

Related thread:

http://forum.dlang.org/post/ofc0lj$2u4h$1@digitalmars.com

[...]
> I do know the difference between a delegate and a function, and I 
> suppose addOnDelete should be defined to take a function instead?

If anything, it should accept both. Not a function instead of a delegate.

> But 
> how can we create a "delegate function" similar to the nested delegate 
> in the first case that works so that we can pass them as delegates?

http://dlang.org/phobos/std_functional.html#toDelegate


[1] 
https://github.com/gtkd-developers/GtkD/blob/5c2ee83aae7425b683709593c5fd44a7ab1db067/generated/gtkd/gtk/Widget.d#L6793
[2] https://dlang.org/spec/expression.html#function_literals


More information about the Digitalmars-d-learn mailing list