The syntax of a bind() call is:
bind(function or delegate pointer { , argument });
argument can be one of:
The result is a function object, which can be called using call(), func() or opCall(). There also exists a convenience function, ptr() which returns a delegate to call/func/opCall
The resulting delegate accepts exactly as many parameters as many distinct dynamic arguments were used.
The types of dynamic parameters are extracted from the bound function itself and when necessary, type negotiation is performed. For example, binding a function
will result in a delegate accepting a single, optimal parameter type. The best type is computed using std.typetuple.DerivedToFront, so in case of an int and a long, long will be selected. Generally, bind will try to find a type that can be implicitly converted to all the other types a given dynamic parameter uses.
which will yield a delegate, that takes the argument, calls f2, then uses the return value of f2 to call f1. Mathematically speaking, it will yield a function composition:
When one function is composed multiple times, it will be called multiple times - Bind does no lazy evaluation, so
will produce a delegate, which, upon calling, will invoke f4 two times to evaluate the arguments for f3 and then call f3
One another feature that bind() supports is automatic tuple expansion. It means that having functions:
Allows them to be bound by writing:
The syntax is:
bindAlias!(Function)(argument, argument, argument, argument, ...);
bindAlias takes advantage of using aliases directly, thus being able to extract default values from functions and not forcing the user to bind them. It doesn't, however mean that the resulting delegate can be called, omitting some of its parameters. It only means that these arguments that have default values in the function provided to bindAlias don't have to be bound explicitly.
Additionally, bindAlias takes care of functions with out/inout parameters, by converting them to pointers internally. A function like:
can be bound using: