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

Reply via email to