Thread overview
Why can I call a function with mismatched parameter type?
Dec 11, 2020
Andrey Zherikov
Dec 11, 2020
rikki cattermole
Dec 11, 2020
rikki cattermole
Dec 11, 2020
Q. Schroll
Dec 11, 2020
vit
Dec 11, 2020
Andrey Zherikov
December 11, 2020
Here is the example:
    alias f1 = (string  ) {}; f1(int   .init);
    alias f2 = (string s) {}; f2(int   .init);
    alias f3 = (int     ) {}; f3(string.init);
    alias f4 = (int i   ) {}; f4(string.init);

"f1" case compiles successfully and all others are not (error is "is not callable using argument types").

Question is why does f1 case compile?

Furthermore even these do compile:
    f1(float.init);

    struct S{}
    f1(S.init);

December 12, 2020
string is not a built in type. It is an alias defined by druntime.

https://github.com/dlang/druntime/blob/master/src/object.d#L35

int on the other hand is defined by the compiler. It understands it.

Further, when the parameter name is not provided it will infer based upon what is passed in. In effect it is templated.
December 12, 2020
On 12/12/2020 12:32 AM, rikki cattermole wrote:
> Further, when the parameter name is not provided it will infer based upon what is passed in. In effect it is templated.

What I meant was: the type is inferred if you only provide a single identifier in a parameter.
December 11, 2020
On Friday, 11 December 2020 at 11:25:22 UTC, Andrey Zherikov wrote:
> Here is the example:
>     alias f1 = (string  ) {}; f1(int   .init);
>     alias f2 = (string s) {}; f2(int   .init);
>     alias f3 = (int     ) {}; f3(string.init);
>     alias f4 = (int i   ) {}; f4(string.init);
>
> "f1" case compiles successfully and all others are not (error is "is not callable using argument types").
>
> Question is why does f1 case compile?
>
> Furthermore even these do compile:
>     f1(float.init);
>
>     struct S{}
>     f1(S.init);



alias f1 = (string  ) {}

"string" isn't type, but name of variable with generic type:

alias f1 = (/*auto type*/ string) {}
December 11, 2020
On Friday, 11 December 2020 at 11:36:05 UTC, vit wrote:
> alias f1 = (string  ) {}
>
> "string" isn't type, but name of variable with generic type:
>
> alias f1 = (/*auto type*/ string) {}

This makes it clear, thanks!

Just checked that this fails as expected: alias f1 = (immutable(char)[]) {}
December 11, 2020
On Friday, 11 December 2020 at 11:32:09 UTC, rikki cattermole wrote:
> string is not a built in type. It is an alias defined by druntime.
>
> https://github.com/dlang/druntime/blob/master/src/object.d#L35
>
> int on the other hand is defined by the compiler. It understands it.

It doesn't magically understand it. `int` is a keyword and thus not a legal identifier.
From a grammar perspective, in `(x, y) { }`, x and y are parsed as types. [1] However, in lambda expressions, when there's a type only and no parameter (according to the grammar) given, the compiler treats a single identifier as a parameter with inferred type. Since `int` is not an identifier, but a keyword, that treatment does not happen. As you explained correctly, `string` is merely an identifier and thus seen as a parameter name.

[1] https://dlang.org/spec/grammar.html#Parameters