{"action":"opened","issue":{"url":"https://api.github.com/repos/crystal-lang/crystal/issues/7001","repository_url":"https://api.github.com/repos/crystal-lang/crystal","labels_url":"https://api.github.com/repos/crystal-lang/crystal/issues/7001/labels{/name}","comments_url":"https://api.github.com/repos/crystal-lang/crystal/issues/7001/comments","events_url":"https://api.github.com/repos/crystal-lang/crystal/issues/7001/events","html_url":"https://github.com/crystal-lang/crystal/issues/7001","id":374806778,"node_id":"MDU6SXNzdWUzNzQ4MDY3Nzg=","number":7001,"title":"NamedTuple with default arguments","user":{"login":"vladfaust","id":7955682,"node_id":"MDQ6VXNlcjc5NTU2ODI=","avatar_url":"https://avatars2.githubusercontent.com/u/7955682?v=4","gravatar_id":"","url":"https://api.github.com/users/vladfaust","html_url":"https://github.com/vladfaust","followers_url":"https://api.github.com/users/vladfaust/followers","following_url":"https://api.github.com/users/vladfaust/following{/other_user}","gists_url":"https://api.github.com/users/vladfaust/gists{/gist_id}","starred_url":"https://api.github.com/users/vladfaust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vladfaust/subscriptions","organizations_url":"https://api.github.com/users/vladfaust/orgs","repos_url":"https://api.github.com/users/vladfaust/repos","events_url":"https://api.github.com/users/vladfaust/events{/privacy}","received_events_url":"https://api.github.com/users/vladfaust/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-10-28T22:34:00Z","updated_at":"2018-10-28T22:34:00Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"Currently `NamedTuple` doesn't allow to have default arguments, i.e. this code won't compile:\r\n\r\n```crystal\r\ndef foo(x : NamedTuple(a: Int32, b: Int32? = nil))\r\n  pp x\r\nend\r\n\r\nfoo(x: {a: 42})\r\n```\r\n\r\nIt would be great if it worked.\r\n\r\n## Use case\r\n\r\nI'm currently implementing an API client for Stripe. Let's see this method: https://stripe.com/docs/api/tokens/create_card. `card` argument is an object. Currently I can't do this:\r\n\r\n```crystal\r\nclass Stripe::Client\r\n  def create_card_token(\r\n    card : NamedTuple(\r\n      exp_month: Int32,\r\n      exp_year: Int32,\r\n      number: String,\r\n      currency: String? = nil,\r\n      cvc: Int32? = nil,\r\n      name: String? = nil,\r\n      address_line1: String? = nil,\r\n      address_line2: String? = nil,\r\n      address_city: String? = nil,\r\n      address_state: String? = nil,\r\n      address_zip: String? = nil,\r\n      address_country: String? = nil)? = nil,\r\n    customer : String? = nil\r\n  )\r\n  end\r\nend\r\n\r\nclient.create_card_token(card: {exp_month: 12, exp_year: 2019, number: \"4242424242424242\", cvc: 123})\r\n```\r\n\r\nBut instead I have to do this:\r\n\r\n```crystal\r\nclass Stripe::Client\r\n  record CreateCardToken::Card,\r\n    exp_month : Int32,\r\n    exp_year : Int32,\r\n    number : String,\r\n    currency : String? = nil,\r\n    cvc : Int32? = nil,\r\n    name : String? = nil,\r\n    address_line1 : String? = nil,\r\n    address_line2 : String? = nil,\r\n    address_city : String? = nil,\r\n    address_state : String? = nil,\r\n    address_zip : String? = nil,\r\n    address_country : String? = nil\r\n\r\n  def create_card_token(\r\n    card : CreateCardToken::Card? = nil,\r\n    customer : String? = nil\r\n  )\r\nend\r\n\r\nclient.create_card_token(card: Stripe::Client::CreateCardToken::Card.new(\r\n  number: \"4242424242424242\",\r\n  exp_month: 12,\r\n  exp_year: 2019,\r\n  cvc: 123,\r\n))\r\n```\r\n\r\nNote: Stripe has a not-so-OOP API, which doesn't allow to use a single `Stripe::Card` object for CRUD methods, so I have to define arguments manually for each method."}}
{"actor":{"display_login":"vladfaust"}}