{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/27804","repository_url":"https://api.github.com/repos/golang/go","labels_url":"https://api.github.com/repos/golang/go/issues/27804/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/27804/comments","events_url":"https://api.github.com/repos/golang/go/issues/27804/events","html_url":"https://github.com/golang/go/issues/27804","id":362750343,"node_id":"MDU6SXNzdWUzNjI3NTAzNDM=","number":27804,"title":"proposal: go 2:  reduce unspecified behaviors of expression evaluation orders in multi-value assignments","user":{"login":"go101","id":22589241,"node_id":"MDQ6VXNlcjIyNTg5MjQx","avatar_url":"https://avatars2.githubusercontent.com/u/22589241?v=4","gravatar_id":"","url":"https://api.github.com/users/go101","html_url":"https://github.com/go101","followers_url":"https://api.github.com/users/go101/followers","following_url":"https://api.github.com/users/go101/following{/other_user}","gists_url":"https://api.github.com/users/go101/gists{/gist_id}","starred_url":"https://api.github.com/users/go101/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go101/subscriptions","organizations_url":"https://api.github.com/users/go101/orgs","repos_url":"https://api.github.com/users/go101/repos","events_url":"https://api.github.com/users/go101/events{/privacy}","received_events_url":"https://api.github.com/users/go101/received_events","type":"User","site_admin":false},"labels":[{"id":150880249,"node_id":"MDU6TGFiZWwxNTA4ODAyNDk=","url":"https://api.github.com/repos/golang/go/labels/Go2","name":"Go2","color":"ffaaaa","default":false},{"id":150880200,"node_id":"MDU6TGFiZWwxNTA4ODAyMDA=","url":"https://api.github.com/repos/golang/go/labels/LanguageChange","name":"LanguageChange","color":"ffaaaa","default":false},{"id":236419512,"node_id":"MDU6TGFiZWwyMzY0MTk1MTI=","url":"https://api.github.com/repos/golang/go/labels/Proposal","name":"Proposal","color":"ededed","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/30","html_url":"https://github.com/golang/go/milestone/30","labels_url":"https://api.github.com/repos/golang/go/milestones/30/labels","id":1373555,"node_id":"MDk6TWlsZXN0b25lMTM3MzU1NQ==","number":30,"title":"Proposal","description":"Proposals that are pending (not yet accepted/rejected).\r\n","creator":{"login":"rsc","id":104030,"node_id":"MDQ6VXNlcjEwNDAzMA==","avatar_url":"https://avatars1.githubusercontent.com/u/104030?v=4","gravatar_id":"","url":"https://api.github.com/users/rsc","html_url":"https://github.com/rsc","followers_url":"https://api.github.com/users/rsc/followers","following_url":"https://api.github.com/users/rsc/following{/other_user}","gists_url":"https://api.github.com/users/rsc/gists{/gist_id}","starred_url":"https://api.github.com/users/rsc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rsc/subscriptions","organizations_url":"https://api.github.com/users/rsc/orgs","repos_url":"https://api.github.com/users/rsc/repos","events_url":"https://api.github.com/users/rsc/events{/privacy}","received_events_url":"https://api.github.com/users/rsc/received_events","type":"User","site_admin":false},"open_issues":240,"closed_issues":600,"state":"open","created_at":"2015-10-24T01:40:49Z","updated_at":"2018-09-24T16:20:36Z","due_on":null,"closed_at":null},"comments":2,"created_at":"2018-09-21T19:43:17Z","updated_at":"2018-09-24T17:30:12Z","closed_at":null,"author_association":"NONE","body":"_(As [this proposal](https://github.com/golang/go/issues/27098) is rejected, I change it as a Go 2 proposal instead.)_\r\n\r\nOne feature of Go is multi-value assignments support. However, currently, the rules of the expression orders in one multi-value assignment are very not specified, which causes many ambiguities in practice. Please read [this](https://github.com/go101/go101/wiki/Some-evaluation-orders-in-multi-value-assignments-are-unspecified) and [this](https://github.com/go101/go101/wiki/An-ambiguity-of-(or-dispute-on)-the-evaluation-order-of-LHS-(left-hand-side)-items-in-a-multi-value-assignment) for details.\r\n\r\nAs a so called C+ language, one of the main goals of Go is to remove as many unspecified behaviors in C as possible, in particular for the unspecified behaviors which may be common encountered. So here I propose Go 2 should specify more on the expression orders in one multi-value assignment.\r\n\r\nCurrently, Go specification specifies:\r\n\r\n> At package level, initialization dependencies determine the evaluation order of individual initialization expressions in variable declarations. Otherwise, when evaluating the operands of an expression, assignment, or return statement, all function calls, method calls, and communication operations are evaluated in lexical left-to-right order. \r\n\r\nBy the rule, the following program must print `1` and `2` for `y` and `z`,\r\nbut the print result for `x` might be `0`, `1` or `2`. The standard Go compiler prints `x` as `2`,\r\nwhich is counterintuitive for most programmers.\r\n\r\n```golang\r\npackage main\r\n\r\nfunc main() {\r\n\ta, b := 0, 0\r\n\tf := func() int {\r\n\t\ta++\r\n\t\tb++\r\n\t\treturn b\r\n\t}\r\n\t\r\n\tx, y, z := a, f(), f()\r\n\tprintln(x, y, z)\r\n}\r\n```\r\n\r\nIf we (or the compiler) rewrite the last multi-value assignment in the above example as\r\n\r\n```golang\r\n\tx, y, z := func() int{return a}(), f(), f()\r\n```\r\n\r\nThen the print result should be `0 1 2` for sure. In other words, there are not any technical obstacles to **evaluate expressions in a multi-value assignment by the from-left-to-right rule** . The reason of why Go specification doesn't adopt this more specified rule might be related to code optimization consideration.\r\n\r\nThe bold line is my proposal.\r\n\r\n[edit: the following content is moved to a new issue: https://github.com/golang/go/issues/27821]\r\n"},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/424058207","html_url":"https://github.com/golang/go/issues/27804#issuecomment-424058207","issue_url":"https://api.github.com/repos/golang/go/issues/27804","id":424058207,"node_id":"MDEyOklzc3VlQ29tbWVudDQyNDA1ODIwNw==","user":{"login":"ianlancetaylor","id":3194333,"node_id":"MDQ6VXNlcjMxOTQzMzM=","avatar_url":"https://avatars2.githubusercontent.com/u/3194333?v=4","gravatar_id":"","url":"https://api.github.com/users/ianlancetaylor","html_url":"https://github.com/ianlancetaylor","followers_url":"https://api.github.com/users/ianlancetaylor/followers","following_url":"https://api.github.com/users/ianlancetaylor/following{/other_user}","gists_url":"https://api.github.com/users/ianlancetaylor/gists{/gist_id}","starred_url":"https://api.github.com/users/ianlancetaylor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ianlancetaylor/subscriptions","organizations_url":"https://api.github.com/users/ianlancetaylor/orgs","repos_url":"https://api.github.com/users/ianlancetaylor/repos","events_url":"https://api.github.com/users/ianlancetaylor/events{/privacy}","received_events_url":"https://api.github.com/users/ianlancetaylor/received_events","type":"User","site_admin":false},"created_at":"2018-09-24T17:30:12Z","updated_at":"2018-09-24T17:30:12Z","author_association":"CONTRIBUTOR","body":"The question is how much freedom the compiler should have to move code around.\r\n\r\nPersonally I'm comfortable with saying that if a single statement writes to a variable other than directly assigning to it, that the order of that write is explicitly unspecified with regard to any reads of the variable in the same statement.  I think we can write a vet check for this--not a 100% accurate vet check, but one that catches cases like the above.  I don't see this case as important in practice, as regardless of the rule that the language adopts this is confusing code, and there is never a reason to write code this way.  I'm fine with a vet check that discourages confusing code."}}
{"actor":{"display_login":"ianlancetaylor"}}