{"action":"created","issue":{"url":"https://api.github.com/repos/babel/babel/issues/1991","labels_url":"https://api.github.com/repos/babel/babel/issues/1991/labels{/name}","comments_url":"https://api.github.com/repos/babel/babel/issues/1991/comments","events_url":"https://api.github.com/repos/babel/babel/issues/1991/events","html_url":"https://github.com/babel/babel/issues/1991","id":94782829,"number":1991,"title":"Flow: return type of Arrow Function","user":{"login":"DmitrySoshnikov","id":244010,"avatar_url":"https://avatars.githubusercontent.com/u/244010?v=3","gravatar_id":"","url":"https://api.github.com/users/DmitrySoshnikov","html_url":"https://github.com/DmitrySoshnikov","followers_url":"https://api.github.com/users/DmitrySoshnikov/followers","following_url":"https://api.github.com/users/DmitrySoshnikov/following{/other_user}","gists_url":"https://api.github.com/users/DmitrySoshnikov/gists{/gist_id}","starred_url":"https://api.github.com/users/DmitrySoshnikov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DmitrySoshnikov/subscriptions","organizations_url":"https://api.github.com/users/DmitrySoshnikov/orgs","repos_url":"https://api.github.com/users/DmitrySoshnikov/repos","events_url":"https://api.github.com/users/DmitrySoshnikov/events{/privacy}","received_events_url":"https://api.github.com/users/DmitrySoshnikov/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-07-13T18:34:30Z","updated_at":"2015-07-15T18:39:50Z","closed_at":null,"body":"Opening this issue to discuss inconsistent position of a return type in an arrow function, and in its type definition.\r\n\r\n```javascript\r\nvar foo = (x: number): number => x;\r\n```\r\n\r\nThis is how currently Flow defines the return type of an arrow. It's a parse error in Babel right now, since Babel parses return types _after_ the arrow:\r\n\r\n```javascript\r\nvar foo = (x: number) => :number x;\r\n```\r\n\r\nThis is due (I guess), since return type of a _function **type**_ is put after:\r\n\r\n```javascript\r\nvar bar = (callback: (x: number) => number) => callback(10);\r\n```\r\n\r\nIf the return type of the function should be before the arrow symbol, we should fix Babel, although, we may probably move it after the arrow to be consistent with a type definition.\r\n\r\nCC @gabelevi"},"comment":{"url":"https://api.github.com/repos/babel/babel/issues/comments/121708242","html_url":"https://github.com/babel/babel/issues/1991#issuecomment-121708242","issue_url":"https://api.github.com/repos/babel/babel/issues/1991","id":121708242,"user":{"login":"gabelevi","id":1887264,"avatar_url":"https://avatars.githubusercontent.com/u/1887264?v=3","gravatar_id":"","url":"https://api.github.com/users/gabelevi","html_url":"https://github.com/gabelevi","followers_url":"https://api.github.com/users/gabelevi/followers","following_url":"https://api.github.com/users/gabelevi/following{/other_user}","gists_url":"https://api.github.com/users/gabelevi/gists{/gist_id}","starred_url":"https://api.github.com/users/gabelevi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gabelevi/subscriptions","organizations_url":"https://api.github.com/users/gabelevi/orgs","repos_url":"https://api.github.com/users/gabelevi/repos","events_url":"https://api.github.com/users/gabelevi/events{/privacy}","received_events_url":"https://api.github.com/users/gabelevi/received_events","type":"User","site_admin":false},"created_at":"2015-07-15T18:39:50Z","updated_at":"2015-07-15T18:39:50Z","body":"Yeah, arrow functions are super ambiguous. Often you don't know if you're dealing with an arrow function until you see the `=>`. For example, `var x = (a, b, c, d)` could either have a grouped sequence expression on the RHS or it could be the beginning of an arrow function. You really don't know until you see the `=>`.\r\n\r\nI used to basically keep parallel parse trees to deal with arrow functions, and then collapse to a single parse tree when I was sure what I was dealing with. This was doable since OCaml was forcing me to properly handle it through expression parsing, but it was a pain and was making it really hard to add annotations to arrow functions. Nowadays I'm using an easier-to-work with rollback scheme. The general idea is this:\r\n\r\n1. [`Try.to_parse env try_assignment_but_not_arrow_function`](https://github.com/facebook/flow/blob/70deb27e986d40c10cc85b27b93b984b901fbc72/src/parser/parser_flow.ml#L1091). This fails if any of these are true\r\n  - It doesn't parse as an assignment expression\r\n  - [It parses as an assignment expression but is followed by an `=>`](https://github.com/facebook/flow/blob/70deb27e986d40c10cc85b27b93b984b901fbc72/src/parser/parser_flow.ml#L1067)\r\n  - [It parses as an assignment expression but is followed by a `:`](https://github.com/facebook/flow/blob/70deb27e986d40c10cc85b27b93b984b901fbc72/src/parser/parser_flow.ml#L1068)\r\n  - [It parses an assignment expression `async` and is followed by an identifier](https://github.com/facebook/flow/blob/70deb27e986d40c10cc85b27b93b984b901fbc72/src/parser/parser_flow.ml#L1072)\r\n2. If that failed then rollback and [`Try.to_parse env try_arrow_function`](https://github.com/facebook/flow/blob/70deb27e986d40c10cc85b27b93b984b901fbc72/src/parser/parser_flow.ml#L1094). This fails only if it fails to parse it as an arrow function\r\n3. If that failed then rollback and just go with [`assignment_but_not_arrow_function`](https://github.com/facebook/flow/blob/70deb27e986d40c10cc85b27b93b984b901fbc72/src/parser/parser_flow.ml#L1101)\r\n\r\nIt is structured this way for performance reasons. Almost all assignment expressions should hit step 1 and be done. Arrow functions are much more rare, and will go through to step 2. Malformed expressions and pathological cases will hit step 3. The example you posted is a pathological case.\r\n\r\n```JavaScript\r\nvar foo = bar ? (foo) : number;\r\n```\r\n\r\nSo we want to parse an assignment expression after the `?`. So first in step 1 we parse `(foo)` as a valid assignment expression. However we see that it's followed by a `:` so we rollback. Now in step 2 we parse `(foo): number` but don't see a `=>` and fail, so we rollback. Finally, in step 3 we parse `(foo)` and finish successfully.\r\n\r\nHope this explanation of how we parse it helps! I haven't dug into acorn yet so I'm not sure how much it helps."}}