Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
January 09, 2017 Delegate parameter name shadows type name | ||||
---|---|---|---|---|
| ||||
This is something that surprised me in a friend's code. (A "friend", hmmm? No, really, it wasn't me! :) ) // Some type of the API struct MyType { int i; } // Some function of the API that takes a delegate void call(void delegate(MyType) dlg) { dlg(MyType(42)); } void main() { /* The programmer simply copied the delegate definition from * the function and used it as-is when passing a lambda: */ call(delegate void(MyType) { /* WAT? Does the following really compile? After all, * MyType.i is NOT a static member! */ if (MyType.i == 42) { // ... } }); } I was surprised to see it compiled and worked but of course MyType at the lambda definition inside main() is not a type name, rather the parameter name. Surprising, but I think this is according to spec. Ali |
January 09, 2017 Re: Delegate parameter name shadows type name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Mon, Jan 09, 2017 at 11:18:02AM -0800, Ali Çehreli via Digitalmars-d-learn wrote: [...] > // Some type of the API > struct MyType { > int i; > } > > // Some function of the API that takes a delegate > void call(void delegate(MyType) dlg) { > dlg(MyType(42)); > } > > void main() { > /* The programmer simply copied the delegate definition from > * the function and used it as-is when passing a lambda: */ > call(delegate void(MyType) { Are you sure this isn't spelt `void delegate(MyType)`? > /* WAT? Does the following really compile? After all, > * MyType.i is NOT a static member! */ > if (MyType.i == 42) { > // ... > } > }); > } > > I was surprised to see it compiled and worked but of course MyType at the lambda definition inside main() is not a type name, rather the parameter name. Surprising, but I think this is according to spec. [...] I think it makes sense relative to your rationalization of it per the spec, but from an objective POV, I think it rightly deserves a WAT?. I can't see anything useful such a construction would allow, besides leading to buggy code caused by unexpected shadowing. I'd say file an enhancement request to make such code a compile error. T -- Ph.D. = Permanent head Damage |
January 09, 2017 Re: Delegate parameter name shadows type name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, January 09, 2017 11:18:02 Ali Çehreli via Digitalmars-d-learn wrote:
> This is something that surprised me in a friend's code.
>
> (A "friend", hmmm? No, really, it wasn't me! :) )
>
> // Some type of the API
> struct MyType {
> int i;
> }
>
> // Some function of the API that takes a delegate
> void call(void delegate(MyType) dlg) {
> dlg(MyType(42));
> }
>
> void main() {
> /* The programmer simply copied the delegate definition from
> * the function and used it as-is when passing a lambda: */
> call(delegate void(MyType) {
> /* WAT? Does the following really compile? After all,
> * MyType.i is NOT a static member! */
> if (MyType.i == 42) {
> // ...
> }
> });
> }
>
> I was surprised to see it compiled and worked but of course MyType at the lambda definition inside main() is not a type name, rather the parameter name. Surprising, but I think this is according to spec.
Well, stuff inside a function is quite free to shadow stuff from outside of it. AFAIK, the only shadowing that's prevented is declarations in a function shadowing other declarations in a function.
- Jonathan M Davis
|
January 09, 2017 Re: Delegate parameter name shadows type name | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 01/09/2017 11:23 AM, H. S. Teoh via Digitalmars-d-learn wrote: > On Mon, Jan 09, 2017 at 11:18:02AM -0800, Ali Çehreli via Digitalmars-d-learn wrote: >> // Some function of the API that takes a delegate >> void call(void delegate(MyType) dlg) { That's a delegate type. >> call(delegate void(MyType) { > > Are you sure this isn't spelt `void delegate(MyType)`? Those two syntaxes always confuse me and I'm never sure without trying which one to use when. :) However, the code is correct in this case because that's a delegate instance. Ali |
January 09, 2017 Re: Delegate parameter name shadows type name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 2017-01-09 20:18, Ali Çehreli wrote: > This is something that surprised me in a friend's code. > > (A "friend", hmmm? No, really, it wasn't me! :) ) > > // Some type of the API > struct MyType { > int i; > } > > // Some function of the API that takes a delegate > void call(void delegate(MyType) dlg) { > dlg(MyType(42)); > } > > void main() { > /* The programmer simply copied the delegate definition from > * the function and used it as-is when passing a lambda: */ > call(delegate void(MyType) { > /* WAT? Does the following really compile? After all, > * MyType.i is NOT a static member! */ > if (MyType.i == 42) { > // ... > } > }); > } > > I was surprised to see it compiled and worked but of course MyType at > the lambda definition inside main() is not a type name, rather the > parameter name. Surprising, but I think this is according to spec. I know this has come up before, and reported as a bug, at least once. Might have been me :). What's confusing is that using a type that has a keyword will make the parameter unnamed of the specified type, just as a regular function: auto a = (int) => 3; // works, a lambda taking an int, no parameter name auto b = (Foo) => 3; // error, cannot infer type of template lambda alias b = (Foo) => 3; // works, since this is an alias, Foo is the parameter name of an unknown type -- /Jacob Carlborg |
January 10, 2017 Re: Delegate parameter name shadows type name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 2017-01-09 20:51, Ali Çehreli wrote: > Those two syntaxes always confuse me and I'm never sure without trying > which one to use when. :) However, the code is correct in this case > because that's a delegate instance. I agree. When it comes to declaring a delegate type, i.e. a variable or function parameter I always think that the syntax is the same as the declaring a regular function, but replacing the function name with "delegate". -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation