{"action":"created","issue":{"url":"https://api.github.com/repos/tc39/proposal-optional-chaining/issues/69","repository_url":"https://api.github.com/repos/tc39/proposal-optional-chaining","labels_url":"https://api.github.com/repos/tc39/proposal-optional-chaining/issues/69/labels{/name}","comments_url":"https://api.github.com/repos/tc39/proposal-optional-chaining/issues/69/comments","events_url":"https://api.github.com/repos/tc39/proposal-optional-chaining/issues/69/events","html_url":"https://github.com/tc39/proposal-optional-chaining/issues/69","id":344125148,"node_id":"MDU6SXNzdWUzNDQxMjUxNDg=","number":69,"title":"(null)?.b should evaluate to null, not undefined","user":{"login":"claudepache","id":3309637,"node_id":"MDQ6VXNlcjMzMDk2Mzc=","avatar_url":"https://avatars2.githubusercontent.com/u/3309637?v=4","gravatar_id":"","url":"https://api.github.com/users/claudepache","html_url":"https://github.com/claudepache","followers_url":"https://api.github.com/users/claudepache/followers","following_url":"https://api.github.com/users/claudepache/following{/other_user}","gists_url":"https://api.github.com/users/claudepache/gists{/gist_id}","starred_url":"https://api.github.com/users/claudepache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/claudepache/subscriptions","organizations_url":"https://api.github.com/users/claudepache/orgs","repos_url":"https://api.github.com/users/claudepache/repos","events_url":"https://api.github.com/users/claudepache/events{/privacy}","received_events_url":"https://api.github.com/users/claudepache/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":53,"created_at":"2018-07-24T17:05:25Z","updated_at":"2018-09-04T09:55:51Z","closed_at":null,"author_association":"COLLABORATOR","body":"In other words, the desugaring of `a?.b` should be `a == null ? a : a.b` (instead of `a == null ? undefined : a.b` as currently specced).\r\n\r\nI gave the following justification for having `a?.b === undefined` when `a === null` in [README#FAQ](https://github.com/tc39/proposal-optional-chaining#faq) (emphasis added on the contended part):\r\n\r\n> Neither `a.b` nor `a?.b` is intended to preserve arbitrary information on the base object `a`, but only _to give information about the property `\"b\"` of that object_. If a property `\"b\"` is absent from a, this is reflected by `a.b === undefined` and `a?.b === undefined`.\r\n>\r\n> In particular, the value null is considered to have no properties; therefore, `(null)?.b` is undefined.\r\n\r\nHowever, that justification is flawed, because of the short-circuiting semantics: when `a` is null, the name of the eventual property (here, `\"b\"`) is not sought, so  that there is no property to give information about.\r\n\r\nThis is clearer when the property name is computed, as in, e.g.: \r\n\r\n```js\r\na?.[++i]\r\na?.[foo(a)] // where `foo(a)` throws a TypeError exception when `a` is null\r\n```\r\n\r\nIn case of `a?.[foo(a)]`, if `a` is null, we do not compute the value of `foo(a)` (and we couldn’t, if `foo(null)` throws a TypeError), so that it doesn’t make sense to try to ”give information about the property `foo(a)` of `a`”.\r\n\r\n---\r\n\r\nI think it is more sensible to apply the usual semantics of short-circuiting operators (`&&` and `||`), at least for consistency reason, namely: In case of short-circuiting, evaluate to the last encountered value. \r\n\r\nIncidentally, that would avoid to clear the null/undefined distinction of the base object, see #65."},"comment":{"url":"https://api.github.com/repos/tc39/proposal-optional-chaining/issues/comments/418309793","html_url":"https://github.com/tc39/proposal-optional-chaining/issues/69#issuecomment-418309793","issue_url":"https://api.github.com/repos/tc39/proposal-optional-chaining/issues/69","id":418309793,"node_id":"MDEyOklzc3VlQ29tbWVudDQxODMwOTc5Mw==","user":{"login":"sndwow","id":18691029,"node_id":"MDQ6VXNlcjE4NjkxMDI5","avatar_url":"https://avatars2.githubusercontent.com/u/18691029?v=4","gravatar_id":"","url":"https://api.github.com/users/sndwow","html_url":"https://github.com/sndwow","followers_url":"https://api.github.com/users/sndwow/followers","following_url":"https://api.github.com/users/sndwow/following{/other_user}","gists_url":"https://api.github.com/users/sndwow/gists{/gist_id}","starred_url":"https://api.github.com/users/sndwow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sndwow/subscriptions","organizations_url":"https://api.github.com/users/sndwow/orgs","repos_url":"https://api.github.com/users/sndwow/repos","events_url":"https://api.github.com/users/sndwow/events{/privacy}","received_events_url":"https://api.github.com/users/sndwow/received_events","type":"User","site_admin":false},"created_at":"2018-09-04T09:55:51Z","updated_at":"2018-09-04T09:55:51Z","author_association":"NONE","body":"```javascript\r\n// this is ugly\r\nconst firstName = message?.body?.user?.firstName || 'default';\r\n\r\n// maybe like this\r\nconst firstName = message.body.user.firstName ?? 'default';\r\n\r\n```"}}
{"actor":{"display_login":"sndwow"}}