On Thursday, 27 December 2018 at 03:52:52 UTC, Johannes Loher
wrote:
Hey all,
I am a bit confused about the inferred types of function
literals which do not name their parameters (something like
`(int) {}`). The confusion arises from the fact that the
inferred type sometimes is `void` (might be the case, because
the function literal is inferred to be a template) and
sometimes it is something like `void function(bool _param_0)
pure nothrow @nogc @safe`. What is really weir is that seems to
depend on the type of the parameter. Here is small example
showing what happens for different parameter types:
https://run.dlang.io/is/xSMZZu
Also note that this only happens for function literals. For
regular functions and member functions, `void` is never
inferred, but only types like `pure nothrow @nogc @safe
void(MyClass _param_0)`.
Has anybody any idea what is going on here? Is this a bug?
As you suspect, some of the function literals are being
interpreted as templates--specifically, the ones whose parameters
are parsed as "identifiers" rather than built-in types. Keep in
mind that from the parser's perspective, `string`, `size_t`, and
`Object` aren't any different from other user-defined type names
or aliases. That they happen to be defined in the D runtime is
irrelevant.
You can see that this is true by running the following example:
alias f = (string) { };
writeln(typeof(f!int).stringof);
Unfortunately, this behavior is mentioned exactly nowhere in the
language spec. Both the section on function literals [1] and the
grammar for function parameters to which it refers [2] fail to
mention any circumstance in which a parameter declaration may
consist only of a name, without a type. As with many things in D,
one can only figure out what the *actual* rules are through trial
and error.
[1] https://dlang.org/spec/expression.html#function_literals
[2] https://dlang.org/spec/function.html#grammar