{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/csharplang/issues/1604","repository_url":"https://api.github.com/repos/dotnet/csharplang","labels_url":"https://api.github.com/repos/dotnet/csharplang/issues/1604/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/csharplang/issues/1604/comments","events_url":"https://api.github.com/repos/dotnet/csharplang/issues/1604/events","html_url":"https://github.com/dotnet/csharplang/issues/1604","id":329118096,"node_id":"MDU6SXNzdWUzMjkxMTgwOTY=","number":1604,"title":"Discussion: Better support for \"Unit\"","user":{"login":"HaloFour","id":10102290,"node_id":"MDQ6VXNlcjEwMTAyMjkw","avatar_url":"https://avatars1.githubusercontent.com/u/10102290?v=4","gravatar_id":"","url":"https://api.github.com/users/HaloFour","html_url":"https://github.com/HaloFour","followers_url":"https://api.github.com/users/HaloFour/followers","following_url":"https://api.github.com/users/HaloFour/following{/other_user}","gists_url":"https://api.github.com/users/HaloFour/gists{/gist_id}","starred_url":"https://api.github.com/users/HaloFour/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HaloFour/subscriptions","organizations_url":"https://api.github.com/users/HaloFour/orgs","repos_url":"https://api.github.com/users/HaloFour/repos","events_url":"https://api.github.com/users/HaloFour/events{/privacy}","received_events_url":"https://api.github.com/users/HaloFour/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":40,"created_at":"2018-06-04T15:59:40Z","updated_at":"2018-06-05T05:56:23Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"There have been numerous proposals looking to add first-class support for a `unit` type to the language.  I'd like to explore the different individual ways that the language could do this without CLR  modification.\r\n\r\nThis is an open discussion and I invite comments and suggestions.  I'll get the ball rolling with some of the ideas I've seen in comments buried in other proposals.\r\n\r\n### Create a `unit` alias\r\n\r\nThe family of types called `System.ValueTuple<...>` were added to the .NET 4.7 framework to support tuple literals in the C# language.  There exists a version with 0 elements, `System.ValueTuple`.  It primarily contains static factory methods for creating instances of the other tuple structs, but it is a `struct` in its own right and can be created.  It is an effectively empty struct with no public fields and is suitable for representing `unit`.\r\n\r\n```cs\r\nFunc<unit> f = () => default(unit); // or just default\r\n\r\n// equivalent to\r\n\r\nFunc<System.ValueTuple> f = () => default(System.ValueTuple);\r\n```\r\n\r\nThe name, however, could leave a little to be desired.  I'll continue to use `System.ValueTuple` for examples here but I'd leave that point open to discussion.\r\n\r\n### Support `()` literal to mean `unit`\r\n\r\nThe syntax `()` could be shorthand to represent `default(unit)`:\r\n\r\n```cs\r\nFunc<unit> f = () => ();\r\n\r\n// equivalent to\r\n\r\nFunc<System.ValueTuple> f = () => default(System.ValueTuple);\r\n```\r\n\r\n### Implicit conversion from `void` to `unit`\r\n\r\nThe compiler could support conversion from `void` to `unit` by emitting IL necessary to push `default(unit)` onto the stack:\r\n\r\n##### Assignments:\r\n\r\n```cs\r\nunit u = Console.WriteLine();\r\n\r\n// equivalent to\r\n\r\nConsole.WriteLine();\r\nSystem.ValueTuple u = default(System.ValueTuple);\r\n```\r\n\r\n##### Lambdas:\r\n\r\n```cs\r\nFunc<string, unit> f = value => Console.WriteLine(value);\r\n// or\r\nFunc<string, unit> f = Console.WriteLine;\r\n\r\n// equivalent to\r\n\r\nFunc<string, System.ValueTuple> f = value => {\r\n    Console.WriteLine(value);\r\n    return default(System.ValueTuple);\r\n};\r\n```"},"comment":{"url":"https://api.github.com/repos/dotnet/csharplang/issues/comments/394590711","html_url":"https://github.com/dotnet/csharplang/issues/1604#issuecomment-394590711","issue_url":"https://api.github.com/repos/dotnet/csharplang/issues/1604","id":394590711,"node_id":"MDEyOklzc3VlQ29tbWVudDM5NDU5MDcxMQ==","user":{"login":"qrli","id":10579882,"node_id":"MDQ6VXNlcjEwNTc5ODgy","avatar_url":"https://avatars3.githubusercontent.com/u/10579882?v=4","gravatar_id":"","url":"https://api.github.com/users/qrli","html_url":"https://github.com/qrli","followers_url":"https://api.github.com/users/qrli/followers","following_url":"https://api.github.com/users/qrli/following{/other_user}","gists_url":"https://api.github.com/users/qrli/gists{/gist_id}","starred_url":"https://api.github.com/users/qrli/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qrli/subscriptions","organizations_url":"https://api.github.com/users/qrli/orgs","repos_url":"https://api.github.com/users/qrli/repos","events_url":"https://api.github.com/users/qrli/events{/privacy}","received_events_url":"https://api.github.com/users/qrli/received_events","type":"User","site_admin":false},"created_at":"2018-06-05T05:56:23Z","updated_at":"2018-06-05T05:56:23Z","author_association":"NONE","body":"I like what [DavidArno proposed](https://github.com/dotnet/csharplang/issues/883#issuecomment-327732475) : instead of adding a new keyword, just use `void`. Then:\r\n```cs\r\nFunc<void> f = () => void;\r\n```\r\nThe void here could be translated to zero-element tuple. I don't see it to be ambiguous with normal `void`. I could be wrong though."}}
{"actor":{"display_login":"qrli"}}