Function template literals - or "just" parameter type inference?

Kenji Hara k.hara.pg at gmail.com
Tue Nov 19 23:50:45 PST 2013


2013/11/20 Jakob Ovrum <jakobovrum at gmail.com>

> As I was preparing a pull request to fill in some documentation, I became
> unsure of a couple of things.
>
> It's clear that the Parameter[1] syntactic element does not account for
> the form `InOut(opt) Identifier`, used when the parameter type is left to
> inference. However, this form is only allowed in function/delegate literal
> expressions, not in declarations of named functions. So, perhaps adding
> this form to Parameter is incorrect, as it's referenced for both. Do we
> need to define a new kind of parameter list for FunctionLiteral[2] in order
> to account for this extra form?


With the lambda `(const x){ ... } `, the lambda parameter name `x` is
parsed as TypeIdentifier.
Then semantic analysis handle the `x` as a lambda parameter name that
requires type inference.

Similarly, with `void foo(const x) {}`, `x` is parsed as TypeIdentifier.
However, semantic analysis will handle it as a Type name of unnamed
function parameter.

The difference is in semantic analysis phase, but not in parsing
phase. Therefore the current Parameter grammar is correct.


> Further, parameter type inference is implemented in terms of (anonymous)
> function templates. However, the documentation only mentions parameter type
> inference once, in the following sentence, under FunctionLiteral[2]:
>
>  If the type of a function literal can be uniquely determined from its
>> context, the[sic] parameter type inference is possible.
>>
>
> Followed by this example:
>
> ---
> void foo(int function(int) fp);
>
> void test() {
>   int function(int) fp = (n) { return n * 2; };
>   // The type of parameter n is inferred to int.
>
>   foo((n) { return n * 2; });
>   // The type of parameter n is inferred to int.
> }
> ---
>
> There is no mention of function templates; is it just an implementation
> detail, or something we should document? If we ever implemented it in some
> other way, would it not have consequences for code that can take function
> templates by alias and possibly call the same function template several
> times but with completely different argument types, which is currently
> valid and possibly useful?
>

Do you use the word "function template" as meaning function/delegate/lambda
literal which requires parameter type inference? If so, it is intended that
current documentation has no mention about template lambdas.

Indeed, current dmd implements such lambdas by using anonymous templates.
As the result, following code is accepted.

template X(alias fun) {
    void test() {
        fun(1);  // OK
        fun!int(1);  // funny, but current dmd accept this.
    }
}
void main() {
    X!(a=>1).test();   // The lambda expression `a=>1` is mostly same as
    // `template __lambda(__T){ auto __lambda(__T a) { return 1; } }`
}

I was not sure that the fun!int is legitimate usage. Therefore, I didn't
mention about the 'template lambda' semantics in documentation.

Therefore currently, it is merely an implementation detail.

Kenji Hara
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20131120/9892d223/attachment.html>


More information about the Digitalmars-d mailing list