www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why can I call a function with mismatched parameter type?

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
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);
Dec 11 2020
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
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.
Dec 11 2020
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
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.
Dec 11 2020
prev sibling parent Q. Schroll <qs.il.paperinik gmail.com> writes:
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
Dec 11 2020
prev sibling parent reply vit <vit vit.vit> writes:
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) {}
Dec 11 2020
parent Andrey Zherikov <andrey.zherikov gmail.com> writes:
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)[]) {}
Dec 11 2020