{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/165","repository_url":"https://api.github.com/repos/Microsoft/TypeScript","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/165/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/165/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/165/events","html_url":"https://github.com/Microsoft/TypeScript/issues/165","id":38337284,"number":165,"title":"Pattern Matching Support","user":{"login":"dignifiedquire","id":790842,"avatar_url":"https://avatars.githubusercontent.com/u/790842?v=3","gravatar_id":"","url":"https://api.github.com/users/dignifiedquire","html_url":"https://github.com/dignifiedquire","followers_url":"https://api.github.com/users/dignifiedquire/followers","following_url":"https://api.github.com/users/dignifiedquire/following{/other_user}","gists_url":"https://api.github.com/users/dignifiedquire/gists{/gist_id}","starred_url":"https://api.github.com/users/dignifiedquire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dignifiedquire/subscriptions","organizations_url":"https://api.github.com/users/dignifiedquire/orgs","repos_url":"https://api.github.com/users/dignifiedquire/repos","events_url":"https://api.github.com/users/dignifiedquire/events{/privacy}","received_events_url":"https://api.github.com/users/dignifiedquire/received_events","type":"User","site_admin":false},"labels":[{"id":114201833,"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Needs%20Proposal","name":"Needs Proposal","color":"556b75","default":false},{"id":113971155,"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Suggestion","name":"Suggestion","color":"006b75","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":27,"created_at":"2014-07-21T19:42:28Z","updated_at":"2016-11-09T20:48:52Z","closed_at":null,"body":"I've seen some short notions about pattern matching on code plex, but no serious discussions around it. As I'm a big fan of it, I've written up some small examples on how I think pattern matching could look in TypeScript.\n\nThis is by far no complete specification, just some ideas that I want to bring forward and have a little discussion around.\n## Function Overloading\n\n``` ts\n// Pattern matching on functions\n\nfunction pickCard {\n  (x: {suit: string; card: number; }[]): number {\n\n    var pickedCard = Math.floor(Math.random() * x.length);\n    return pickedCard;  \n\n  }\n  (x: number): {suit: string; card: number; } {\n\n    var pickedSuit = Math.floor(x / 13);\n    return { suit: suits[pickedSuit], card: x % 13 };\n\n  }\n} \n```\n\n``` js\n// Translation of functions.ts using sparkler\n// https://github.com/natefaubion/sparkler\n\nfunction pickCard(x) {\n  [...{ suit @ String, card @ number }] =>  {\n    var pickedCard = Math.floor(Math.random() * x.length);\n    return pickedCard;  \n  }\n  x @ Number => {\n    var pickedSuit = Math.floor(x / 13);\n    return { suit: suits[pickedSuit], card: x % 13 };\n  }\n} \n```\n## `Match` statement\n\n``` ts\n// Pattern matching using match\n\nfunction whoami (x: any): string {\n\n  match x {\n    case { name: string, type: 'person' }: \n        return 'Person: ' + name;\n\n    case { name: string, type: 'animal' }: \n        return 'Animal: ' + name;\n\n    default: \n        return 'Unkown you';\n  }\n} \n```\n\n``` js\n// Pattern matching using match translated\n\nfunction whoami (x) {\n\n  match x {\n    case { name @ String, type: 'person' }: \n        return 'Person: ' + name;\n\n    case { name @ String, type: 'animal' }: \n        return 'Animal: ' + name;\n\n    default: \n        return 'Unkown you';\n  }\n\n} \n```\n"},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/259522477","html_url":"https://github.com/Microsoft/TypeScript/issues/165#issuecomment-259522477","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/165","id":259522477,"user":{"login":"xogeny","id":1498808,"avatar_url":"https://avatars.githubusercontent.com/u/1498808?v=3","gravatar_id":"","url":"https://api.github.com/users/xogeny","html_url":"https://github.com/xogeny","followers_url":"https://api.github.com/users/xogeny/followers","following_url":"https://api.github.com/users/xogeny/following{/other_user}","gists_url":"https://api.github.com/users/xogeny/gists{/gist_id}","starred_url":"https://api.github.com/users/xogeny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xogeny/subscriptions","organizations_url":"https://api.github.com/users/xogeny/orgs","repos_url":"https://api.github.com/users/xogeny/repos","events_url":"https://api.github.com/users/xogeny/events{/privacy}","received_events_url":"https://api.github.com/users/xogeny/received_events","type":"User","site_admin":false},"created_at":"2016-11-09T20:48:52Z","updated_at":"2016-11-09T20:48:52Z","body":"Much of what is being asked for in pattern matching is already possible in TS 2.0.0 (Thanks!).  It is achieved without storing any runtime type information too.  But for me, the one thing that would be nice would be more intuitive syntax.  For example, right now I can write code like this.\r\n\r\n```\r\nclass Foo {\r\n  public name: string;\r\n}\r\n\r\nclass Bar {\r\n  public title: string;\r\n}\r\n\r\ntype Stringable = A | B;\r\n\r\nfunction stringOf(a: Stringable): string {\r\n  if (a instanceof Foo) return a.name;\r\n  return a.title;\r\n}\r\n```\r\n\r\nThat's great.  But something like this would just be easier to read:\r\n\r\n```\r\nfunction stringOf(a: Stringable): string {\r\n  a match {\r\n     case Foo: return a.name;\r\n     case Bar: return a.title;\r\n }\r\n}\r\n```\r\n\r\nMy point here is that using this strictly with classes could avoid some of the \"having to include runtime information\" because you could piggy back off of what is already included (i.e., the same information that `instanceof` is using).  Of course, instrumenting this with destructuring and guards would be really cool too! e.g., \r\n\r\n```\r\nfunction lengthOf(a: Stringable): number {\r\n  a match {\r\n    case Foo({ name }) if name: return name.length;\r\n    case Bar({ title }) if title: return title.length;\r\n    default: return 0;\r\n  }\r\n}\r\n```\r\n\r\nMy guess is that what's already been implemented with type narrowing could be completely reused here.  As far as I can tell, this is just syntactic sugar for:\r\n\r\n```\r\nfunction lengthOf(a: Stringable): number {\r\n  if (a instanceof Foo && a.name) return a.name.length;\r\n  else if (a instanceof Bar && b.title) return a.title.length;\r\n  else return 0;\r\n}\r\n```\r\n\r\n...with the same possibilities for detection mutual exhaustion.\r\n\r\nOr am I missing something?\r\n"}}
{"actor":{"display_login":"xogeny"}}