{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/14697","repository_url":"https://api.github.com/repos/dotnet/roslyn","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/14697/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/14697/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/14697/events","html_url":"https://github.com/dotnet/roslyn/issues/14697","id":184765921,"number":14697,"title":"Implicit Variable Declarations","user":{"login":"Kaelum","id":1742782,"avatar_url":"https://avatars.githubusercontent.com/u/1742782?v=3","gravatar_id":"","url":"https://api.github.com/users/Kaelum","html_url":"https://github.com/Kaelum","followers_url":"https://api.github.com/users/Kaelum/followers","following_url":"https://api.github.com/users/Kaelum/following{/other_user}","gists_url":"https://api.github.com/users/Kaelum/gists{/gist_id}","starred_url":"https://api.github.com/users/Kaelum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Kaelum/subscriptions","organizations_url":"https://api.github.com/users/Kaelum/orgs","repos_url":"https://api.github.com/users/Kaelum/repos","events_url":"https://api.github.com/users/Kaelum/events{/privacy}","received_events_url":"https://api.github.com/users/Kaelum/received_events","type":"User","site_admin":false},"labels":[{"id":169838071,"url":"https://api.github.com/repos/dotnet/roslyn/labels/Area-Language%20Design","name":"Area-Language Design","color":"5319e7","default":false},{"id":166677091,"url":"https://api.github.com/repos/dotnet/roslyn/labels/Feature%20Request","name":"Feature Request","color":"fc2929","default":false},{"id":166377946,"url":"https://api.github.com/repos/dotnet/roslyn/labels/Language-C%23","name":"Language-C#","color":"207de5","default":false},{"id":326633537,"url":"https://api.github.com/repos/dotnet/roslyn/labels/New%20Language%20Feature%20-%20Pattern%20Matching","name":"New Language Feature - Pattern Matching","color":"bfd4f2","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":20,"created_at":"2016-10-24T07:18:15Z","updated_at":"2016-11-21T02:19:14Z","closed_at":null,"body":"The C# Design Language Notes for Jul 15, 2016 in #12939 are deeply concerning, and should be raising a red flag for everyone.  Allowing a C based language to leak like this, throws out the more than 45 years of scoping rules that exist.  It also allows variable declarations to be hidden, making them extremely difficult to find.  I am saying this now, as people are just starting to realize the gravity of #12939.  As an additional side effect #14651 was created, and there will very definitely be many more to come if this is allowed to remain as-is.  All of this, just to allow a \"nice to have feature\"?\n\nMy proposal is to revert the scoping rules back to the way that they were prior to #12939, and change the implementation of the `is int x` and `out int y` \"explicit variable declarations\" to be \"implicit variable declarations\".  Meaning, that if `x` exists, is in scope, and is an `int`, use it.  If `x` exists, is in scope, and is not an `int`, a compile time error is thrown.  If `x` exists, but is not in scope, or `x` does not exist, create `x` in the scope that it is implicitly introduced.\n\nIf anyone needs the \"leaking\" functionality of #12939, no changes need to be made.  We have that ability in C#6 and earlier, where you just explicitly declare the variable in the scope that you need it.  However, for those who would like to use \"temporary\" variables, which was the original vision of this, you will have many options.  Consider the following:\n\nFor those who don't want the leaks:\n\n```\nint? age = (o is int i || (o is string s && int.TryParse(s, out int i)) ? i : null);\n\n// i and s are not in scope here.\n```\n\nFor those who like it leaky:\n\n```\nint i;\nstring s;\n\n// The int in the out parameter is completely optional in this case.\nint? age = (o is int i || (o is string s && int.TryParse(s, out int i)) ? i : null);\n\n// i and s are in scope here, and no compile time errors.\n```\n\nIn no case would I want `i` or `s` to forever be used.  They are temporary variables, much like the variables used in Lamba expressions.  Who wants `i` to be taken away from being used in a `for` statement.  @MadsTorgersen also brought up the \"bouncer pattern\" and a few scenarios for its use.  I will say flat out that I don't buy into all of those scenarios as being valid.  If it smells bad, and looks bad, then it most likely is bad.  Would anyone truly excpect the `i` below to remain in scope?\n\n```\nif (!(o is int i)) throw new ArgumentException(\"Not an int\", nameof(o));\n```\n\nIf I truly want `i` to persist, I would explicitly declare it:\n\n```\nint i;\n\nif (!(o is int i)) throw new ArgumentException(\"Not an int\", nameof(o));\n```\n\nRemember, it is our duty as developers to question anything, and everything, that someone is trying to force down our throats.  It took well over 10 years to create the 1998 C++ specification, and I thank everyone who was involved for ensuring that absurd proposals like #12939 never saw the light of day.\n\nHave an AWESOME day!\n"},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/261827045","html_url":"https://github.com/dotnet/roslyn/issues/14697#issuecomment-261827045","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/14697","id":261827045,"user":{"login":"Kaelum","id":1742782,"avatar_url":"https://avatars.githubusercontent.com/u/1742782?v=3","gravatar_id":"","url":"https://api.github.com/users/Kaelum","html_url":"https://github.com/Kaelum","followers_url":"https://api.github.com/users/Kaelum/followers","following_url":"https://api.github.com/users/Kaelum/following{/other_user}","gists_url":"https://api.github.com/users/Kaelum/gists{/gist_id}","starred_url":"https://api.github.com/users/Kaelum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Kaelum/subscriptions","organizations_url":"https://api.github.com/users/Kaelum/orgs","repos_url":"https://api.github.com/users/Kaelum/repos","events_url":"https://api.github.com/users/Kaelum/events{/privacy}","received_events_url":"https://api.github.com/users/Kaelum/received_events","type":"User","site_admin":false},"created_at":"2016-11-21T02:19:14Z","updated_at":"2016-11-21T02:19:14Z","body":"> Yes. that is understood. If you want a narrow scope, you can't have that. But you can at least still use the feature and not take advantage of the wider scope if that's not of any interest to you.\r\n\r\nHow?  If we require narrow scoping, how can we use the feature?  Are you saying that we need to pollute the variable scope with huge numbers of declarations?\r\n\r\nThis is my final comment:\r\n`out` was improperly implemented, and now you are making changes that will forever destroy the language for that faulty operator.  I'm sorry if you don't agree, or don't understand, but I can't agree with anything that you are saying.\r\n\r\nSincerely"}}
{"actor":{"display_login":"Kaelum"}}